Comparison

util/datamanager.lua @ 13137:b417a49cc31b

util.datamanager: Halve size of list index Instead of storing (start, length) tuples, store the offset to the end of items and derive length using the previous entry.
author Kim Alvefur <zash@zash.se>
date Fri, 14 May 2021 05:49:35 +0200
parent 13134:638f627e707f
child 13180:48622b89f570
comparison
equal deleted inserted replaced
13136:396db0e7084f 13137:b417a49cc31b
258 return true, pos; 258 return true, pos;
259 end 259 end
260 260
261 local index_fmt, index_item_size, index_magic; 261 local index_fmt, index_item_size, index_magic;
262 if string.packsize then 262 if string.packsize then
263 index_fmt = "TT"; -- struct { size_t start, size_t length } 263 index_fmt = "T"; -- offset to the end of the item, length can be derived from two index items
264 index_item_size = string.packsize(index_fmt); 264 index_item_size = string.packsize(index_fmt);
265 index_magic = string.pack(index_fmt, 7767639, 1); -- Magic string: T9 for "prosody", version number 265 index_magic = string.pack(index_fmt, 7767639 + 1); -- Magic string: T9 for "prosody", version number
266 end 266 end
267 267
268 local function list_append(username, host, datastore, data) 268 local function list_append(username, host, datastore, data)
269 if not data then return; end 269 if not data then return; end
270 if callback(username, host, datastore) == false then return true; end 270 if callback(username, host, datastore) == false then return true; end
277 datastore, msg, where, username or "nil", host or "nil"); 277 datastore, msg, where, username or "nil", host or "nil");
278 return ok, msg; 278 return ok, msg;
279 end 279 end
280 if string.packsize then 280 if string.packsize then
281 local offset = type(msg) == "number" and msg or 0; 281 local offset = type(msg) == "number" and msg or 0;
282 local index_entry = string.pack(index_fmt, offset, #data); 282 local index_entry = string.pack(index_fmt, offset + #data);
283 if offset == 0 then 283 if offset == 0 then
284 index_entry = index_magic .. index_entry; 284 index_entry = index_magic .. index_entry;
285 end 285 end
286 local ok, off = append(username, host, datastore, "lidx", index_entry); 286 local ok, off = append(username, host, datastore, "lidx", index_entry);
287 off = off or 0; 287 off = off or 0;
356 end 356 end
357 357
358 local function store_list_index(username, host, datastore, index) 358 local function store_list_index(username, host, datastore, index)
359 local data = { index_magic }; 359 local data = { index_magic };
360 for i, v in ipairs(index) do 360 for i, v in ipairs(index) do
361 data[i + 1] = string.pack(index_fmt, v.start, v.length); 361 data[i + 1] = string.pack(index_fmt, v.start + v.length);
362 end 362 end
363 local filename = getpath(username, host, datastore, "lidx"); 363 local filename = getpath(username, host, datastore, "lidx");
364 return atomic_store(filename, t_concat(data)); 364 return atomic_store(filename, t_concat(data));
365 end 365 end
366 366
367 local index_mt = { 367 local index_mt = {
368 __index = function(t, i) 368 __index = function(t, i)
369 if type(i) ~= "number" or i % 1 ~= 0 or i < 1 then 369 if type(i) ~= "number" or i % 1 ~= 0 or i < 0 then
370 return 370 return
371 end 371 end
372 if i < 0 then 372 if i <= 0 then
373 return 373 return 0
374 end 374 end
375 local fh = t.file; 375 local fh = t.file;
376 local pos = i * index_item_size; 376 local pos = (i - 1) * index_item_size;
377 if fh:seek("set", pos) ~= pos then 377 if fh:seek("set", pos) ~= pos then
378 return nil 378 return nil
379 end 379 end
380 local data = fh:read(index_item_size); 380 local data = fh:read(index_item_size * 2);
381 if not data then 381 if not data or #data ~= index_item_size * 2 then
382 return nil 382 return nil
383 end 383 end
384 local start, length = string.unpack(index_fmt, data); 384 local start, next_pos = string.unpack(index_fmt .. index_fmt, data);
385 if pos == 0 then
386 start = 0
387 end
388 local length = next_pos - start;
385 local v = { start = start; length = length }; 389 local v = { start = start; length = length };
386 t[i] = v; 390 t[i] = v;
387 return v; 391 return v;
388 end; 392 end;
389 __len = function(t) 393 __len = function(t)