util/memcache.lua

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;