aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_storage_memory.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mod_storage_memory.lua')
-rw-r--r--plugins/mod_storage_memory.lua78
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;