Mercurial > prosody-hg
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 |
| parents | 638f627e707f |
| children | 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) |
