diff options
author | Kim Alvefur <zash@zash.se> | 2023-07-12 15:03:24 +0200 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2023-07-12 15:03:24 +0200 |
commit | d03a9b2f7e39d35b36f9b707045166d2851438af (patch) | |
tree | 78c8fd6e6f904c073fd58afd111017a0fbe1f487 | |
parent | 33986e97b7d8819b8dc613d1ba878bc6db4f2163 (diff) | |
download | prosody-d03a9b2f7e39d35b36f9b707045166d2851438af.tar.gz prosody-d03a9b2f7e39d35b36f9b707045166d2851438af.zip |
mod_storage_internal: Implement efficient deletion of oldest archive items
Using the new shift function in datamanager, either the oldest items are
removed or all the later items are moved into a new file that replaces
the old.
Hidden behind a feature flag for now.
-rw-r--r-- | plugins/mod_storage_internal.lua | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/plugins/mod_storage_internal.lua b/plugins/mod_storage_internal.lua index cd6ca0c4..0d3f2da6 100644 --- a/plugins/mod_storage_internal.lua +++ b/plugins/mod_storage_internal.lua @@ -14,6 +14,8 @@ local host = module.host; local archive_item_limit = module:get_option_number("storage_archive_item_limit", 10000); local archive_item_count_cache = cache.new(module:get_option("storage_archive_item_limit_cache_size", 1000)); +local use_shift = module:get_option_boolean("storage_archive_experimental_fast_delete", false); + local driver = {}; function driver:open(store, typ) @@ -342,12 +344,32 @@ function archive:users() return datamanager.users(host, self.store, "list"); end +function archive:trim(username, to_when) + local list, err = datamanager.list_open(username, host, self.store); + if not list then return list,err;end + -- luacheck: ignore 211/exact + local i, exact = binary_search(list, function(item) + local when = item.when or datetime.parse(item.attr.stamp); + return to_when - when; + end); + -- TODO if exact then ... off by one? + if i == 1 then return 0; end + local ok, err = datamanager.list_shift(username, host, self.store, i); + if not ok then return ok, err; end + return i-1; +end + function archive:delete(username, query) local cache_key = jid_join(username, host, self.store); if not query or next(query) == nil then archive_item_count_cache:set(cache_key, nil); return datamanager.list_store(username, host, self.store, nil); end + + if use_shift and next(query) == "end" and next(query, "end") == nil then + return self:trim(username, query["end"]); + end + local items, err = datamanager.list_load(username, host, self.store); if not items then if err then |