Software /
code /
prosody
Comparison
util/datamanager.lua @ 13186:affaf6d08d26
util.datamanager: Pad list writes to avoid crossing block boundaries
By padding items so that they do not cross block boundaries, it becomes
eaiser to delete whole blocks with fallocate() without cutting items
in half, improving efficiency of such operations.
Since list stores are used for message archives, where the most common
deletion operation would be of the oldest entires, at the top of the
file. With this, all blocks that contain items to be removed could be
deleted without needing to read, delete and write out the whole file.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 07 Jun 2023 00:39:30 +0200 |
parent | 13185:b57f45165e1e |
child | 13231:6a11d92ae436 |
comparison
equal
deleted
inserted
replaced
13185:b57f45165e1e | 13186:affaf6d08d26 |
---|---|
30 -- Extract directory separator from package.config (an undocumented string that comes with lua) | 30 -- Extract directory separator from package.config (an undocumented string that comes with lua) |
31 local path_separator = assert ( package.config:match ( "^([^\n]+)" ) , "package.config not in standard form" ) | 31 local path_separator = assert ( package.config:match ( "^([^\n]+)" ) , "package.config not in standard form" ) |
32 | 32 |
33 local prosody = prosody; | 33 local prosody = prosody; |
34 | 34 |
35 local blocksize = 0x1000; | |
35 local raw_mkdir = lfs.mkdir; | 36 local raw_mkdir = lfs.mkdir; |
36 local atomic_append; | 37 local atomic_append; |
37 local remove_blocks; | 38 local remove_blocks; |
38 local ENOENT = 2; | 39 local ENOENT = 2; |
39 pcall(function() | 40 pcall(function() |
242 return atomic_store(filename, data); | 243 return atomic_store(filename, data); |
243 -- File did probably not exist, let's create it | 244 -- File did probably not exist, let's create it |
244 end | 245 end |
245 | 246 |
246 local pos = f:seek("end"); | 247 local pos = f:seek("end"); |
248 if (blocksize-(pos%blocksize)) < (#data%blocksize) then | |
249 -- pad to blocksize with newlines so that the next item is both on a new | |
250 -- block and a new line | |
251 atomic_append(f, ("\n"):rep(blocksize-(pos%blocksize))); | |
252 pos = f:seek("end"); | |
253 end | |
247 | 254 |
248 local ok, msg = atomic_append(f, data); | 255 local ok, msg = atomic_append(f, data); |
249 | 256 |
250 if not ok then | 257 if not ok then |
251 f:close(); | 258 f:close(); |