| 1 | local now = os.time; |
| 2 | |
| 3 | module("memcache", package.seeall); |
| 4 | |
| 5 | local max_expires_seconds = 60*60*24*30; |
| 6 | |
| 7 | function new() |
| 8 | local cache = {}; |
| 9 | |
| 10 | local _data = {}; |
| 11 | local _flags = {}; |
| 12 | local _expiry = {}; |
| 13 | local _deleted = {}; |
| 14 | |
| 15 | function cache:set(key, flags, expires, data) |
| 16 | _flags[key] = flags; |
| 17 | if expires > 0 then |
| 18 | if expires <= max_expires_seconds then |
| 19 | expires = now() + expires; |
| 20 | end |
| 21 | _expiry[key] = expires; |
| 22 | end |
| 23 | _deleted[key] = nil; |
| 24 | _data[key] = data; |
| 25 | return true, true; |
| 26 | end |
| 27 | |
| 28 | function cache:add(key, flags, expires, data) |
| 29 | if not(_data[key]) and (not(_deleted[key]) or _deleted[key] < now()) then |
| 30 | return self:set(key, flags, expires, data); |
| 31 | end |
| 32 | return true, false; -- No error, but data was not stored |
| 33 | end |
| 34 | |
| 35 | function cache:replace(key, flags, expires, data) |
| 36 | if _data[key] and (not(_deleted[key]) or _deleted[key] < now()) then |
| 37 | return self:set(key, flags, expires, data); |
| 38 | end |
| 39 | return true, false; -- No error, but data was not stored |
| 40 | end |
| 41 | |
| 42 | function cache:exists(key) |
| 43 | return not not _data[key]; |
| 44 | end |
| 45 | |
| 46 | function cache:get(key) |
| 47 | local expires = _expiry[key]; |
| 48 | if expires and expires < now() then |
| 49 | self:delete(key); |
| 50 | end |
| 51 | return _flags[key], tostring(_data[key]); |
| 52 | end |
| 53 | |
| 54 | function cache:delete(key, time) |
| 55 | local existed = _data[key]; |
| 56 | _flags[key], _data[key], _expiry[key] = nil, nil, nil; |
| 57 | if existed and time then |
| 58 | if time <= max_expires_seconds then |
| 59 | time = now() + time; |
| 60 | end |
| 61 | _deleted[key] = time; |
| 62 | end |
| 63 | return true, existed; |
| 64 | end |
| 65 | |
| 66 | function cache:incr(key, amount) |
| 67 | local current_value = tonumber((select(2, self:get(key)))) or 0; |
| 68 | local new_value = (current_value + amount)%4294967296; |
| 69 | local ok, err = cache:set(key, 0, 0, new_value); |
| 70 | if not ok then |
| 71 | return ok, err; |
| 72 | end |
| 73 | return ok, new_value; |
| 74 | end |
| 75 | |
| 76 | function cache:decr(key, amount) |
| 77 | local current_value = tonumber((select(2, self:get(key)))) or 0; |
| 78 | local new_value = math.max(0, current_value - amount); |
| 79 | local ok, err = cache:set(key, 0, 0, new_value); |
| 80 | if not ok then |
| 81 | return ok, err; |
| 82 | end |
| 83 | return ok, new_value; |
| 84 | end |
| 85 | |
| 86 | return cache; |
| 87 | end |
| 88 | |
| 89 | return _M; |