# HG changeset patch # User Kim Alvefur # Date 1423772226 -3600 # Node ID 59fdf4f123438258c232605995470a5d856434ad # Parent 8b997d9cf09eb6402e93cf13ea34de1c70d02d6c mod_storage_memory: Add support for archive stores diff -r 8b997d9cf09e -r 59fdf4f12343 mod_storage_memory/mod_storage_memory.lua --- a/mod_storage_memory/mod_storage_memory.lua Thu Feb 12 15:13:50 2015 +0100 +++ b/mod_storage_memory/mod_storage_memory.lua Thu Feb 12 21:17:06 2015 +0100 @@ -39,9 +39,96 @@ return true; end +local archive_store = {}; +archive_store.__index = archive_store; + +function archive_store:append(username, key, when, with, value) + local a = self.store[username]; + if not a then + a = {}; + self.store[username] = a; + end + local i = #a+1; + local v = { key = key, when = when, with = with, value = value }; + if not key or a[key] then + key = tostring(a):match"%x+$"..tostring(v):match"%x+$"; + v.key = key; + end + a[i] = v; + a[key] = i; + return true; +end + +local function archive_iter (a, start, stop, step, limit, when_start, when_end, match_with) + local item, when, with; + local count = 0; + coroutine.yield(true); -- Ready + for i = start, stop, step do + item = a[i]; + when, with = item.when, item.with; + if when >= when_start and when_end >= when and (not match_with or match_with == with) then + coroutine.yield(item.key, item.value, when, with); + count = count + 1; + if limit and count >= limit then return end + end + end +end + +function archive_store:find(username, query) + local a = self.store[username] or {}; + local start, stop, step = 1, #a, 1; + local qstart, qend, qwith = -math.huge, math.huge; + local limit; + if query then + module:log("debug", "query included") + if query.reverse then + start, stop, step = stop, start, -1; + if query.before then + start = a[query.before]; + end + elseif query.after then + start = a[query.after]; + end + limit = query.limit; + qstart = query.start or qstart; + qend = query["end"] or qend; + end + if not start then return nil, "invalid-key"; end + local iter = coroutine.wrap(archive_iter); + iter(a, start, stop, step, limit, qstart, qend, qwith); + return iter; +end + +function archive_store:delete(username, query) + if not query or next(query) == nil then + self.store[username] = nil; + return true; + end + local old = self.store[username]; + if not old then return true; end + local qstart = query.start or -math.huge; + local qend = query["end"] or math.huge; + local qwith = query.with; + local new = {}; + self.store[username] = new; + local t; + for i = 1, #old do + i = old[i]; + t = i.when; + if not(qstart >= t and qend <= t and (not qwith or i.with == qwith)) then + self:append(username, i.key, t, i.with, i.value); + end + end + if #new == 0 then + self.store[username] = nil; + end + return true; +end + local stores = { keyval = keyval_store; map = map_store; + archive = archive_store; } local driver = {};