Software /
code /
prosody
Changeset
13185:b57f45165e1e
util.datamanager: Efficiently remove whole blocks to shift lists
Using the new pposix.remove_blocks() it should be very performant to
delete whole sections of a file, given a supporting file system.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 12 Jul 2023 11:45:12 +0200 |
parents | 13184:d16845afb3e2 |
children | 13186:affaf6d08d26 |
files | util/datamanager.lua |
diffstat | 1 files changed, 40 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/util/datamanager.lua Wed Jun 07 05:07:03 2023 +0200 +++ b/util/datamanager.lua Wed Jul 12 11:45:12 2023 +0200 @@ -34,11 +34,13 @@ local raw_mkdir = lfs.mkdir; local atomic_append; +local remove_blocks; local ENOENT = 2; pcall(function() local pposix = require "prosody.util.pposix"; raw_mkdir = pposix.mkdir or raw_mkdir; -- Doesn't trample on umask atomic_append = pposix.atomic_append; + remove_blocks = pposix.remove_blocks; ENOENT = pposix.ENOENT or ENOENT; end); @@ -572,6 +574,44 @@ return true; end + if remove_blocks then + local f, err = io_open(list_filename, "r+"); + if not f then + return f, err; + end + + local diff = 0; + local block_offset = 0; + if offset % 0x1000 ~= 0 then + -- Not an even block boundary, we will have to overwrite + diff = offset % 0x1000; + block_offset = offset - diff; + end + + if block_offset == 0 then + log("debug", "") + else + local ok, err = remove_blocks(f, 0, block_offset); + log("debug", "remove_blocks(%s, 0, %d)", f, block_offset); + if not ok then + log("warn", "Could not remove blocks from %q[%d, %d]: %s", list_filename, 0, block_offset, err); + else + if diff ~= 0 then + -- overwrite unaligned leftovers + if f:seek("set", 0) then + local wrote, err = f:write(string.rep("\n", diff)); + if not wrote then + log("error", "Could not blank out %q[%d, %d]: %s", list_filename, 0, diff, err); + end + end + end + local ok, err = f:close(); + shift_index(index_filename, index, trim_to, offset); -- Shift or delete the index + return ok, err; + end + end + end + local r, err = io_open(list_filename, "r"); if not r then return nil, err;