Software /
code /
prosody
Comparison
util/datamanager.lua @ 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 |
parent | 13183:33b114fbb5de |
child | 13186:affaf6d08d26 |
comparison
equal
deleted
inserted
replaced
13184:d16845afb3e2 | 13185:b57f45165e1e |
---|---|
32 | 32 |
33 local prosody = prosody; | 33 local prosody = prosody; |
34 | 34 |
35 local raw_mkdir = lfs.mkdir; | 35 local raw_mkdir = lfs.mkdir; |
36 local atomic_append; | 36 local atomic_append; |
37 local remove_blocks; | |
37 local ENOENT = 2; | 38 local ENOENT = 2; |
38 pcall(function() | 39 pcall(function() |
39 local pposix = require "prosody.util.pposix"; | 40 local pposix = require "prosody.util.pposix"; |
40 raw_mkdir = pposix.mkdir or raw_mkdir; -- Doesn't trample on umask | 41 raw_mkdir = pposix.mkdir or raw_mkdir; -- Doesn't trample on umask |
41 atomic_append = pposix.atomic_append; | 42 atomic_append = pposix.atomic_append; |
43 remove_blocks = pposix.remove_blocks; | |
42 ENOENT = pposix.ENOENT or ENOENT; | 44 ENOENT = pposix.ENOENT or ENOENT; |
43 end); | 45 end); |
44 | 46 |
45 local _ENV = nil; | 47 local _ENV = nil; |
46 -- luacheck: std none | 48 -- luacheck: std none |
568 end | 570 end |
569 | 571 |
570 local offset = new_first.start; | 572 local offset = new_first.start; |
571 if offset == 0 then | 573 if offset == 0 then |
572 return true; | 574 return true; |
575 end | |
576 | |
577 if remove_blocks then | |
578 local f, err = io_open(list_filename, "r+"); | |
579 if not f then | |
580 return f, err; | |
581 end | |
582 | |
583 local diff = 0; | |
584 local block_offset = 0; | |
585 if offset % 0x1000 ~= 0 then | |
586 -- Not an even block boundary, we will have to overwrite | |
587 diff = offset % 0x1000; | |
588 block_offset = offset - diff; | |
589 end | |
590 | |
591 if block_offset == 0 then | |
592 log("debug", "") | |
593 else | |
594 local ok, err = remove_blocks(f, 0, block_offset); | |
595 log("debug", "remove_blocks(%s, 0, %d)", f, block_offset); | |
596 if not ok then | |
597 log("warn", "Could not remove blocks from %q[%d, %d]: %s", list_filename, 0, block_offset, err); | |
598 else | |
599 if diff ~= 0 then | |
600 -- overwrite unaligned leftovers | |
601 if f:seek("set", 0) then | |
602 local wrote, err = f:write(string.rep("\n", diff)); | |
603 if not wrote then | |
604 log("error", "Could not blank out %q[%d, %d]: %s", list_filename, 0, diff, err); | |
605 end | |
606 end | |
607 end | |
608 local ok, err = f:close(); | |
609 shift_index(index_filename, index, trim_to, offset); -- Shift or delete the index | |
610 return ok, err; | |
611 end | |
612 end | |
573 end | 613 end |
574 | 614 |
575 local r, err = io_open(list_filename, "r"); | 615 local r, err = io_open(list_filename, "r"); |
576 if not r then | 616 if not r then |
577 return nil, err; | 617 return nil, err; |