comparison mod_storage_memory/mod_storage_memory.lua @ 1608:59fdf4f12343

mod_storage_memory: Add support for archive stores
author Kim Alvefur <zash@zash.se>
date Thu, 12 Feb 2015 21:17:06 +0100
parents 8b997d9cf09e
children 54c8a0cb2996
comparison
equal deleted inserted replaced
1607:8b997d9cf09e 1608:59fdf4f12343
37 end 37 end
38 userstore[key] = data; 38 userstore[key] = data;
39 return true; 39 return true;
40 end 40 end
41 41
42 local archive_store = {};
43 archive_store.__index = archive_store;
44
45 function archive_store:append(username, key, when, with, value)
46 local a = self.store[username];
47 if not a then
48 a = {};
49 self.store[username] = a;
50 end
51 local i = #a+1;
52 local v = { key = key, when = when, with = with, value = value };
53 if not key or a[key] then
54 key = tostring(a):match"%x+$"..tostring(v):match"%x+$";
55 v.key = key;
56 end
57 a[i] = v;
58 a[key] = i;
59 return true;
60 end
61
62 local function archive_iter (a, start, stop, step, limit, when_start, when_end, match_with)
63 local item, when, with;
64 local count = 0;
65 coroutine.yield(true); -- Ready
66 for i = start, stop, step do
67 item = a[i];
68 when, with = item.when, item.with;
69 if when >= when_start and when_end >= when and (not match_with or match_with == with) then
70 coroutine.yield(item.key, item.value, when, with);
71 count = count + 1;
72 if limit and count >= limit then return end
73 end
74 end
75 end
76
77 function archive_store:find(username, query)
78 local a = self.store[username] or {};
79 local start, stop, step = 1, #a, 1;
80 local qstart, qend, qwith = -math.huge, math.huge;
81 local limit;
82 if query then
83 module:log("debug", "query included")
84 if query.reverse then
85 start, stop, step = stop, start, -1;
86 if query.before then
87 start = a[query.before];
88 end
89 elseif query.after then
90 start = a[query.after];
91 end
92 limit = query.limit;
93 qstart = query.start or qstart;
94 qend = query["end"] or qend;
95 end
96 if not start then return nil, "invalid-key"; end
97 local iter = coroutine.wrap(archive_iter);
98 iter(a, start, stop, step, limit, qstart, qend, qwith);
99 return iter;
100 end
101
102 function archive_store:delete(username, query)
103 if not query or next(query) == nil then
104 self.store[username] = nil;
105 return true;
106 end
107 local old = self.store[username];
108 if not old then return true; end
109 local qstart = query.start or -math.huge;
110 local qend = query["end"] or math.huge;
111 local qwith = query.with;
112 local new = {};
113 self.store[username] = new;
114 local t;
115 for i = 1, #old do
116 i = old[i];
117 t = i.when;
118 if not(qstart >= t and qend <= t and (not qwith or i.with == qwith)) then
119 self:append(username, i.key, t, i.with, i.value);
120 end
121 end
122 if #new == 0 then
123 self.store[username] = nil;
124 end
125 return true;
126 end
127
42 local stores = { 128 local stores = {
43 keyval = keyval_store; 129 keyval = keyval_store;
44 map = map_store; 130 map = map_store;
131 archive = archive_store;
45 } 132 }
46 133
47 local driver = {}; 134 local driver = {};
48 135
49 function driver:open(store, typ) 136 function driver:open(store, typ)