Software / code / prosody
Comparison
util/datamanager.lua @ 13183:33b114fbb5de
util.datamanager: Add way to efficiently remove first items in a list
Copying data without parsing it should be more performant than parsing
it serializing back.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Wed, 12 Jul 2023 11:42:41 +0200 |
| parent | 13182:c48ae06e24d6 |
| child | 13185:b57f45165e1e |
comparison
equal
deleted
inserted
replaced
| 13182:c48ae06e24d6 | 13183:33b114fbb5de |
|---|---|
| 504 return index, err; | 504 return index, err; |
| 505 end | 505 end |
| 506 return setmetatable({ file = file; index = index }, indexed_list_mt); | 506 return setmetatable({ file = file; index = index }, indexed_list_mt); |
| 507 end | 507 end |
| 508 | 508 |
| 509 local function shift_index(index_filename, index, trim_to, offset) | |
| 510 local index_scratch = index_filename .. "~"; | |
| 511 local new_index, err = io_open(index_scratch, "w"); | |
| 512 if not new_index then | |
| 513 os_remove(index_filename); | |
| 514 return "deleted", err; | |
| 515 end | |
| 516 | |
| 517 local ok, err = new_index:write(index_magic); | |
| 518 if not ok then | |
| 519 new_index:close(); | |
| 520 os_remove(index_filename); | |
| 521 os_remove(index_scratch); | |
| 522 return "deleted", err; | |
| 523 end | |
| 524 | |
| 525 if not index.file or not index.file:seek("set", index_item_size * trim_to) then | |
| 526 new_index:close(); | |
| 527 os_remove(index_filename); | |
| 528 os_remove(index_scratch); | |
| 529 return "deleted"; | |
| 530 else | |
| 531 local pack, unpack = string.pack, string.unpack; | |
| 532 for item in index.file:lines(index_item_size) do | |
| 533 local ok, err = new_index:write(pack(index_fmt, unpack(index_fmt, item) - offset)); | |
| 534 if not ok then | |
| 535 os_remove(index_filename); | |
| 536 os_remove(index_scratch); | |
| 537 return "deleted", err; | |
| 538 end | |
| 539 end | |
| 540 local ok, err = new_index:close(); | |
| 541 if not ok then | |
| 542 os_remove(index_filename); | |
| 543 os_remove(index_scratch); | |
| 544 return "deleted", err; | |
| 545 end | |
| 546 return os_rename(index_scratch, index_filename); | |
| 547 end | |
| 548 end | |
| 549 | |
| 550 local function list_shift(username, host, datastore, trim_to) | |
| 551 if trim_to == 1 then | |
| 552 return true | |
| 553 end | |
| 554 if type(trim_to) ~= "number" or trim_to < 1 then | |
| 555 return nil, "invalid-argument"; | |
| 556 end | |
| 557 local list_filename = getpath(username, host, datastore, "list"); | |
| 558 local index_filename = getpath(username, host, datastore, "lidx"); | |
| 559 local index, err = get_list_index(username, host, datastore); | |
| 560 if not index then | |
| 561 return nil, err; | |
| 562 end | |
| 563 | |
| 564 local new_first = index[trim_to]; | |
| 565 if not new_first then | |
| 566 os_remove(index_filename); | |
| 567 return os_remove(list_filename); | |
| 568 end | |
| 569 | |
| 570 local offset = new_first.start; | |
| 571 if offset == 0 then | |
| 572 return true; | |
| 573 end | |
| 574 | |
| 575 local r, err = io_open(list_filename, "r"); | |
| 576 if not r then | |
| 577 return nil, err; | |
| 578 end | |
| 579 local w, err = io_open(list_filename .. "~", "w"); | |
| 580 if not w then | |
| 581 return nil, err; | |
| 582 end | |
| 583 r:seek("set", offset); | |
| 584 for block in r:lines(0x1000) do | |
| 585 local ok, err = w:write(block); | |
| 586 if not ok then | |
| 587 return nil, err; | |
| 588 end | |
| 589 end | |
| 590 r:close(); | |
| 591 local ok, err = w:close(); | |
| 592 if not ok then | |
| 593 return nil, err; | |
| 594 end | |
| 595 shift_index(index_filename, index, trim_to, offset) | |
| 596 return os_rename(list_filename .. "~", list_filename); | |
| 597 end | |
| 598 | |
| 599 | |
| 509 local type_map = { | 600 local type_map = { |
| 510 keyval = "dat"; | 601 keyval = "dat"; |
| 511 list = "list"; | 602 list = "list"; |
| 512 } | 603 } |
| 513 | 604 |
| 607 path_decode = decode; | 698 path_decode = decode; |
| 608 path_encode = encode; | 699 path_encode = encode; |
| 609 | 700 |
| 610 build_list_index = build_list_index; | 701 build_list_index = build_list_index; |
| 611 list_open = list_open; | 702 list_open = list_open; |
| 703 list_shift = list_shift; | |
| 612 }; | 704 }; |