1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 22:48:11 +00:00

LibSQL: Keep track of free heap blocks when trimming storage

When overwriting existing heap storage that requires fewer blocks, make
sure to free all remaining blocks so they can be reused in the future.
This commit is contained in:
Jelle Raaijmakers 2023-05-24 14:53:43 +02:00 committed by Tim Flynn
parent c5ebc4bb40
commit a6abc1697f
3 changed files with 75 additions and 6 deletions

View file

@ -96,3 +96,34 @@ TEST_CASE(heap_overwrite_large_storage)
auto stored_longest_string = TRY_OR_FAIL(heap->read_storage(storage_block_id));
EXPECT_EQ(longest_string.bytes(), stored_longest_string.bytes());
}
TEST_CASE(heap_reuse_freed_blocks_after_storage_trim)
{
ScopeGuard guard([]() { MUST(Core::System::unlink(db_path)); });
auto heap = create_heap();
// First, write storage spanning 4 blocks
auto first_index = heap->request_new_block_index();
StringBuilder builder;
MUST(builder.try_append_repeated('x', SQL::Block::DATA_SIZE * 4));
auto long_string = builder.string_view();
TRY_OR_FAIL(heap->write_storage(first_index, long_string.bytes()));
MUST(heap->flush());
auto original_heap_size = MUST(heap->file_size_in_bytes());
// Then, overwrite the first storage and reduce it to 2 blocks
builder.clear();
MUST(builder.try_append_repeated('x', SQL::Block::DATA_SIZE * 2));
long_string = builder.string_view();
TRY_OR_FAIL(heap->write_storage(first_index, long_string.bytes()));
MUST(heap->flush());
auto heap_size_after_reduction = MUST(heap->file_size_in_bytes());
EXPECT(heap_size_after_reduction <= original_heap_size);
// Now add the second storage spanning 2 blocks - heap should not have grown compared to the original storage
auto second_index = heap->request_new_block_index();
TRY_OR_FAIL(heap->write_storage(second_index, long_string.bytes()));
MUST(heap->flush());
auto heap_size_after_second_storage = MUST(heap->file_size_in_bytes());
EXPECT(heap_size_after_second_storage <= original_heap_size);
}