diff options
Diffstat (limited to 'plugins/mod_storage_memory.lua')
-rw-r--r-- | plugins/mod_storage_memory.lua | 78 |
1 files changed, 62 insertions, 16 deletions
diff --git a/plugins/mod_storage_memory.lua b/plugins/mod_storage_memory.lua index cbbc5e29..9659f9e7 100644 --- a/plugins/mod_storage_memory.lua +++ b/plugins/mod_storage_memory.lua @@ -1,4 +1,5 @@ local serialize = require "util.serialization".serialize; +local array = require "util.array"; local envload = require "util.envload".envload; local st = require "util.stanza"; local is_stanza = st.is_stanza or function (s) return getmetatable(s) == st.stanza_mt end @@ -113,25 +114,70 @@ function archive_store:delete(username, query) self.store[username or NULL] = nil; return true; end - local old = self.store[username or NULL]; - 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 or NULL] = 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, i.value(), t, i.with); + local items = self.store[username or NULL]; + if not items then + -- Store is empty + return 0; + end + items = array(items); + local count_before = #items; + if query then + if query.key then + items:filter(function (item) + return item.key ~= query.key; + end); + end + if query.with then + items:filter(function (item) + return item.with ~= query.with; + end); + end + if query.start then + items:filter(function (item) + return item.when < query.start; + end); + end + if query["end"] then + items:filter(function (item) + return item.when > query["end"]; + end); + end + if query.truncate and #items > query.truncate then + if query.reverse then + -- Before: { 1, 2, 3, 4, 5, } + -- After: { 1, 2, 3 } + for i = #items, query.truncate + 1, -1 do + items[i] = nil; + end + else + -- Before: { 1, 2, 3, 4, 5, } + -- After: { 3, 4, 5 } + local offset = #items - query.truncate; + for i = 1, #items do + items[i] = items[i+offset]; + end + end end end - if #new == 0 then - self.store[username or NULL] = nil; + local count = count_before - #items; + if count == 0 then + return 0; -- No changes, skip write end - return true; + setmetatable(items, nil); + + do -- re-index by key + for k in pairs(items) do + if type(k) == "string" then + items[k] = nil; + end + end + + for i = 1, #items do + items[ items[i].key ] = i; + end + end + + return count; end archive_store.purge = _purge_store; |