diff --git a/src/blockstore/blockstore_heap.cpp b/src/blockstore/blockstore_heap.cpp index f7cbf02e..d869bd72 100644 --- a/src/blockstore/blockstore_heap.cpp +++ b/src/blockstore/blockstore_heap.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -23,9 +24,15 @@ #define HEAP_INFLIGHT_COMPACTED 4 #define HEAP_INFLIGHT_GC 8 +static inline heap_list_item_t *list_item(heap_entry_t *wr) +{ + return (heap_list_item_t*)((uint8_t*)wr - offsetof(struct heap_list_item_t, entry)); +} + heap_entry_t *blockstore_heap_t::prev(heap_entry_t *wr) { - return wr->prev == (heap_entry_t*)1 ? NULL : wr->prev; + auto li = list_item(wr); + return li->prev ? &li->prev->entry : NULL; } uint32_t blockstore_heap_t::get_simple_entry_size() @@ -168,17 +175,8 @@ void heap_entry_t::set_big_location(blockstore_heap_t *heap, uint64_t location) uint32_t heap_entry_t::calc_crc32c() { auto old_crc32c = crc32c; - auto old_block = block_num; - auto old_prev = prev; - auto old_next = next; - block_num = 0; - prev = NULL; - next = NULL; crc32c = 0; uint32_t res = ::crc32c(0, (uint8_t*)this, size); - block_num = old_block; - prev = old_prev; - next = old_next; crc32c = old_crc32c; return res; } @@ -230,7 +228,7 @@ blockstore_heap_t::~blockstore_heap_t() } int blockstore_heap_t::read_blocks(uint64_t disk_offset, uint64_t disk_size, uint8_t *buf, - std::function handle_write, std::function handle_block) + std::function handle_write, std::function handle_block) { for (uint64_t buf_offset = 0; buf_offset < disk_size; buf_offset += dsk->meta_block_size) { @@ -286,10 +284,7 @@ int blockstore_heap_t::read_blocks(uint64_t disk_offset, uint64_t disk_size, uin block_num, block_offset, expected_crc32c, wr->crc32c); return EDOM; } - wr->prev = NULL; - wr->next = NULL; - wr->block_num = block_num; - handle_write(wr); + handle_write(block_num, wr); block_offset += wr->size; } handle_block(block_num, block_offset, buf+buf_offset); @@ -301,10 +296,13 @@ int blockstore_heap_t::load_blocks(uint64_t disk_offset, uint64_t size, uint8_t { entries_loaded = 0; uint32_t used_space = 0; - return read_blocks(disk_offset, size, buf, [&](heap_entry_t *wr_orig) + return read_blocks(disk_offset, size, buf, [&](uint32_t block_num, heap_entry_t *wr_orig) { - heap_entry_t *wr = (heap_entry_t*)malloc_or_die(wr_orig->size); - memcpy(wr, wr_orig, wr_orig->size); + heap_list_item_t *li = (heap_list_item_t*)malloc_or_die(wr_orig->size + sizeof(heap_list_item_t) - sizeof(heap_entry_t)); + li->block_num = block_num; + li->prev = li->next = NULL; + memcpy(&li->entry, wr_orig, wr_orig->size); + auto wr = &li->entry; if (wr->lsn > next_lsn) { next_lsn = wr->lsn; @@ -314,67 +312,66 @@ int blockstore_heap_t::load_blocks(uint64_t disk_offset, uint64_t size, uint8_t auto & idx = inode_idx[wr->stripe]; if (!idx.ptr) { - idx.ptr = wr; + idx.ptr = li; } else { - auto prev_wr = idx.ptr; - if (!prev_wr || prev_wr->is_before(wr)) + auto prev_li = idx.ptr; + if (!prev_li || prev_li->entry.is_before(wr)) { - wr->prev = prev_wr; - if (prev_wr) + li->prev = prev_li; + if (prev_li) { - prev_wr->next = wr; + prev_li->next = li; } if (wr->is_overwrite()) { // Mark all previous entries as garbage - while (prev_wr) + while (prev_li) { - auto prev_prev = prev(wr); - prev_wr->set_garbage(); - block_info[prev_wr->block_num].has_garbage = true; // FIXME modify_alloc - prev_wr = prev_prev; + prev_li->entry.set_garbage(); + block_info[prev_li->block_num].has_garbage = true; // FIXME modify_alloc + prev_li = prev_li->prev; } } // Insert on top - idx.ptr = wr; + idx.ptr = li; } else { while (true) { - auto prev_prev = prev(prev_wr); - if (!prev_prev || prev_prev->is_before(wr)) + auto prev_prev = prev_li->prev; + if (!prev_prev || prev_prev->entry.is_before(wr)) { break; } - prev_wr = prev_prev; + prev_li = prev_prev; } - if (prev_wr->is_overwrite()) + if (prev_li->entry.is_overwrite()) { // Mark as garbage wr->set_garbage(); - block_info[wr->block_num].has_garbage = true; + block_info[li->block_num].has_garbage = true; } // Insert before - wr->prev = prev_wr->prev; - if (prev_wr->prev) - prev_wr->prev->next = wr; - prev_wr->prev = wr; - wr->next = prev_wr; + li->prev = prev_li->prev; + if (prev_li->prev) + prev_li->prev->next = li; + prev_li->prev = li; + li->next = prev_li; } } if (!wr->is_garbage()) { used_space += wr->size; } - auto & inf = block_info[wr->block_num]; + auto & inf = block_info[li->block_num]; if (!inf.entries.size()) { inf.entries.reserve(dsk->meta_block_size / sizeof(heap_entry_t)); } - inf.entries.push_back(wr); + inf.entries.push_back(li); }, [&](uint32_t block_num, uint32_t last_offset, uint8_t *buf) { modify_alloc(block_num, [&](heap_block_info_t & inf) @@ -393,7 +390,7 @@ void blockstore_heap_t::fill_recheck_queue() { for (auto & op: ip.second) { - auto wr = op.second.ptr; + auto wr = &op.second.ptr->entry; bool prev_intent = false; while (wr) { @@ -418,7 +415,7 @@ void blockstore_heap_t::mark_used_blocks() for (auto & op: ip.second) { bool added = false; - auto wr = op.second.ptr; + auto wr = &op.second.ptr->entry; while (wr) { if (wr->type() == BS_HEAP_SMALL_WRITE) @@ -452,20 +449,20 @@ void blockstore_heap_t::recheck_buffer(heap_entry_t *cwr, uint8_t *buf) { // write entry is invalid, erase it and all newer entries auto & inode_idx = block_index[get_pg_id(cwr->inode, cwr->stripe)][cwr->inode]; - auto wr = inode_idx[cwr->stripe].ptr; + auto li = inode_idx[cwr->stripe].ptr; int rolled_back = 0; auto free_entry = [&]() { - uint32_t block_num = wr->block_num; - auto prev = wr->prev; - auto wr_size = wr->size; - free(wr); + uint32_t block_num = li->block_num; + auto prev = li->prev; + auto wr_size = li->entry.size; + free(li); modify_alloc(block_num, [&](heap_block_info_t & inf) { inf.used_space -= wr_size; for (auto it = inf.entries.begin(); it != inf.entries.end(); it++) { - if (*it == wr) + if (*it == li) { inf.entries.erase(it); break; @@ -473,25 +470,26 @@ void blockstore_heap_t::recheck_buffer(heap_entry_t *cwr, uint8_t *buf) } }); recheck_modified_blocks.insert(block_num); - wr = prev; + li = prev; rolled_back++; }; - while (wr && wr != cwr) + while (li && cwr != &li->entry) { free_entry(); } - assert(wr == cwr); - if (wr->prev) + assert(li); + if (li->prev) { fprintf(stderr, "Notice: %u unfinished writes to %jx:%jx v%jx since lsn %ju, rolling back\n", - rolled_back+1, wr->inode, wr->stripe, prev(wr)->version, prev(wr)->lsn); - inode_idx[wr->stripe].ptr = wr->prev; + rolled_back+1, cwr->inode, cwr->stripe, prev(cwr)->version, prev(cwr)->lsn); + inode_idx[cwr->stripe].ptr = li->prev; + li->prev->next = NULL; } else { fprintf(stderr, "Notice: the whole object %jx:%jx only has unfinished writes, rolling back\n", - wr->inode, wr->stripe); - inode_idx.erase(wr->stripe); + cwr->inode, cwr->stripe); + inode_idx.erase(cwr->stripe); } free_entry(); } @@ -808,10 +806,10 @@ heap_entry_t *blockstore_heap_t::read_entry(object_id oid) { return NULL; } - return stripe_it->second.ptr; + return &stripe_it->second.ptr->entry; } -int blockstore_heap_t::allocate_entry(uint32_t entry_size, uint32_t *block_num, heap_entry_t **entry, bool allow_last_free) +int blockstore_heap_t::allocate_entry(uint32_t entry_size, uint32_t *block_num, bool allow_last_free) { if (last_allocated_block != UINT32_MAX) { @@ -882,7 +880,7 @@ int blockstore_heap_t::allocate_entry(uint32_t entry_size, uint32_t *block_num, size_t i = 0, j = 0; for (; i < inf.entries.size(); i++) { - if (inf.entries[i]->is_garbage()) + if (inf.entries[i]->entry.is_garbage()) { // old entry invalidated by a newer one, mark it as freeable on block write // assign a 'virtual' LSN to track GC completion @@ -890,7 +888,7 @@ int blockstore_heap_t::allocate_entry(uint32_t entry_size, uint32_t *block_num, uint64_t gc_lsn = ++next_lsn; inf.mod_lsn = inf.mod_lsn ? inf.mod_lsn : gc_lsn; inf.mod_lsn_to = gc_lsn; - push_inflight_lsn(gc_lsn, inf.entries[i], HEAP_INFLIGHT_GC); + push_inflight_lsn(gc_lsn, &inf.entries[i]->entry, HEAP_INFLIGHT_GC); } else if (j != i) { @@ -901,10 +899,6 @@ int blockstore_heap_t::allocate_entry(uint32_t entry_size, uint32_t *block_num, inf.has_garbage = false; } *block_num = last_allocated_block; - *entry = (heap_entry_t*)malloc_or_die(entry_size); - if (!inf.entries.size()) - inf.entries.reserve(dsk->meta_block_size / sizeof(heap_entry_t)); - inf.entries.push_back(*entry); modify_alloc(last_allocated_block, [&](heap_block_info_t & inf) { inf.used_space += entry_size; @@ -912,12 +906,11 @@ int blockstore_heap_t::allocate_entry(uint32_t entry_size, uint32_t *block_num, return 0; } -int blockstore_heap_t::add_entry(uint32_t wr_size, heap_entry_t *old_head, uint32_t *modified_block, +int blockstore_heap_t::add_entry(uint32_t wr_size, uint32_t *modified_block, bool allow_last_free, std::function fill_entry) { - heap_entry_t *new_wr = NULL; uint32_t block_num; - int res = allocate_entry(wr_size, &block_num, &new_wr, allow_last_free); + int res = allocate_entry(wr_size, &block_num, allow_last_free); if (res != 0) { return res; @@ -926,7 +919,12 @@ int blockstore_heap_t::add_entry(uint32_t wr_size, heap_entry_t *old_head, uint3 { *modified_block = block_num; } + auto li = (heap_list_item_t*)malloc_or_die(wr_size + sizeof(heap_list_item_t) - sizeof(heap_entry_t)); + auto new_wr = &li->entry; auto & inf = block_info.at(block_num); + if (!inf.entries.size()) + inf.entries.reserve(dsk->meta_block_size / sizeof(heap_entry_t)); + inf.entries.push_back(li); assert(!inf.mod_lsn_to || inf.mod_lsn_to == next_lsn); new_wr->lsn = ++next_lsn; fill_entry(new_wr); @@ -938,40 +936,39 @@ int blockstore_heap_t::add_entry(uint32_t wr_size, heap_entry_t *old_head, uint3 (new_wr->is_overwrite() ? HEAP_INFLIGHT_COMPACTED : 0) | (new_wr->is_compactable() ? HEAP_INFLIGHT_COMPACTABLE : 0)); auto & idx = block_index[get_pg_id(oid.inode, oid.stripe)][oid.inode][oid.stripe]; - old_head = idx.ptr; - if (old_head && !old_head->is_before(new_wr)) + auto old_head = idx.ptr; + if (old_head && !old_head->entry.is_before(new_wr)) { // BIG_WRITE may be inserted into the middle of the sequence during compaction // and it overrides SMALL_WRITEs and COMMITs with the same LSN // However, all entries of other types (say DELETE) override previous ones - auto next_wr = old_head; + auto next_li = old_head; while (true) { - auto nn = prev(next_wr); - if (!nn || nn->is_before(new_wr)) + if (!next_li->prev || next_li->prev->entry.is_before(new_wr)) break; - next_wr = nn; + next_li = next_li->prev; } - auto prev_wr = prev(next_wr); + auto prev_wr = &next_li->prev->entry; // may be an identical big_write entry when we "punch holes" in the bitmap assert(prev_wr && prev_wr->type() != BS_HEAP_DELETE && (prev_wr->type() != BS_HEAP_BIG_WRITE || prev_wr->version == new_wr->version)); // Insert between and - new_wr->prev = next_wr->prev; - if (next_wr->prev) - next_wr->prev->next = new_wr; - next_wr->prev = new_wr; - new_wr->next = next_wr; + li->prev = next_li->prev; + if (next_li->prev) + next_li->prev->next = li; + next_li->prev = li; + li->next = next_li; } else { - new_wr->prev = idx.ptr; - new_wr->next = NULL; + li->prev = idx.ptr; + li->next = NULL; if (idx.ptr) - idx.ptr->next = new_wr; - idx.ptr = new_wr; + idx.ptr->next = li; + idx.ptr = li; } - new_wr->block_num = block_num; + li->block_num = block_num; new_wr->size = wr_size; new_wr->crc32c = new_wr->calc_crc32c(); return 0; @@ -989,7 +986,7 @@ int blockstore_heap_t::add_small_write(object_id oid, heap_entry_t *old_head, ui return EINVAL; } uint32_t wr_size = get_small_entry_size(offset, len); - return add_entry(wr_size, old_head, modified_block, false, [&](heap_entry_t *wr) + return add_entry(wr_size, modified_block, false, [&](heap_entry_t *wr) { wr->entry_type = type; wr->inode = oid.inode; @@ -1019,7 +1016,7 @@ int blockstore_heap_t::add_big_write(object_id oid, heap_entry_t *old_head, bool return EINVAL; } uint32_t wr_size = get_big_entry_size(); - return add_entry(wr_size, old_head, modified_block, false, [&](heap_entry_t *wr) + return add_entry(wr_size, modified_block, false, [&](heap_entry_t *wr) { wr->entry_type = BS_HEAP_BIG_WRITE | (stable ? BS_HEAP_STABLE : 0); wr->inode = oid.inode; @@ -1061,7 +1058,7 @@ int blockstore_heap_t::add_compact(heap_entry_t *obj, uint64_t to_lsn, uint32_t if (!has_entry) { uint64_t compact_lsn = obj->lsn; - return add_entry(get_simple_entry_size(), obj, modified_block, false, [&](heap_entry_t *wr) + return add_entry(get_simple_entry_size(), modified_block, false, [&](heap_entry_t *wr) { wr->entry_type = BS_HEAP_DELETE|BS_HEAP_STABLE; wr->inode = obj->inode; @@ -1078,7 +1075,7 @@ int blockstore_heap_t::add_compact(heap_entry_t *obj, uint64_t to_lsn, uint32_t } auto oid = (object_id){ .inode = obj->inode, .stripe = obj->stripe }; uint32_t wr_size = get_big_entry_size(); - return add_entry(wr_size, obj, modified_block, true, [&](heap_entry_t *new_wr) + return add_entry(wr_size, modified_block, true, [&](heap_entry_t *new_wr) { // obj and old_wr are invalid, re-read them - the block could have been compacted obj = read_entry(oid); @@ -1187,7 +1184,7 @@ int blockstore_heap_t::add_punch_holes(heap_entry_t *obj, uint64_t to_lsn, uint6 int blockstore_heap_t::add_simple(heap_entry_t *obj, uint64_t version, uint32_t *modified_block, uint32_t entry_type) { uint32_t wr_size = get_simple_entry_size(); - return add_entry(wr_size, obj, modified_block, false, [&](heap_entry_t *wr) + return add_entry(wr_size, modified_block, false, [&](heap_entry_t *wr) { wr->entry_type = entry_type; wr->inode = obj->inode; @@ -1391,7 +1388,7 @@ void blockstore_heap_t::mark_garbage_up_to(heap_entry_t *wr) while (wr && !wr->is_garbage()) { auto prev_wr = prev(wr); - mark_garbage(wr->block_num, wr, used_big); + mark_garbage(list_item(wr)->block_num, wr, used_big); wr = prev_wr; } } @@ -1586,7 +1583,7 @@ int blockstore_heap_t::list_objects(uint32_t pg_num, object_id min_oid, object_i { continue; } - heap_entry_t *obj = stripe_pair.second.ptr; + heap_entry_t *obj = &stripe_pair.second.ptr->entry; assert(obj->inode == oid.inode && obj->stripe == oid.stripe); uint64_t stable_version = 0; auto first_wr = obj; @@ -1710,10 +1707,10 @@ void blockstore_heap_t::get_meta_block(uint32_t block_num, uint8_t *buffer) { auto & inf = block_info.at(block_num); size_t pos = 0; - for (auto entry: inf.entries) + for (auto li: inf.entries) { - memcpy(buffer+pos, entry, entry->size); - pos += entry->size; + memcpy(buffer+pos, &li->entry, li->entry.size); + pos += li->entry.size; } memset(buffer+pos, 0, dsk->meta_block_size-pos); } @@ -1845,8 +1842,8 @@ void blockstore_heap_t::apply_inflight(heap_inflight_lsn_t & inflight) else if (inflight.flags & HEAP_INFLIGHT_GC) { // Remove entry - auto prev = wr->prev; - auto next = wr->next; + auto prev = list_item(wr)->prev; + auto next = list_item(wr)->next; if (prev) { prev->next = next; @@ -1858,13 +1855,13 @@ void blockstore_heap_t::apply_inflight(heap_inflight_lsn_t & inflight) else { next->prev = prev; - if (!prev && next->entry_type == (BS_HEAP_DELETE|BS_HEAP_STABLE)) + if (!prev && next->entry.entry_type == (BS_HEAP_DELETE|BS_HEAP_STABLE)) { // free BS_HEAP_DELETEs when their refcount becomes 1 - mark_garbage(next->block_num, next, UINT32_MAX); + mark_garbage(next->block_num, &next->entry, UINT32_MAX); } } - free(wr); + free(list_item(wr)); } } diff --git a/src/blockstore/blockstore_heap.h b/src/blockstore/blockstore_heap.h index 8b1a3d37..c3e50410 100644 --- a/src/blockstore/blockstore_heap.h +++ b/src/blockstore/blockstore_heap.h @@ -45,9 +45,6 @@ struct __attribute__((__packed__)) heap_entry_t uint64_t inode; uint64_t stripe; uint64_t version; - uint32_t block_num; // FIXME this shit - heap_entry_t *prev; // FIXME and this shit too should be moved into a separate structure - heap_entry_t *next; // FIXME and this shit too // uint8_t[] external_bitmap // uint8_t[] internal_bitmap @@ -87,6 +84,14 @@ struct __attribute__((__packed__)) heap_big_write_t uint32_t block_num; }; +struct __attribute__((__packed__)) heap_list_item_t +{ + heap_list_item_t *prev; + heap_list_item_t *next; + uint32_t block_num; + heap_entry_t entry; +}; + struct heap_object_mvcc_t { uint32_t readers = 0; @@ -99,7 +104,7 @@ struct heap_block_info_t uint64_t mod_lsn = 0, mod_lsn_to = 0; // only 1 block write of LSN sequence is allowed at a moment bool is_writing: 1; bool has_garbage: 1; - std::vector entries; + std::vector entries; }; struct heap_inflight_lsn_t @@ -116,7 +121,7 @@ struct heap_compact_t struct heap_idx_t { - heap_entry_t *ptr; + heap_list_item_t *ptr; }; using i64hash_t = robin_hood::hash; @@ -174,8 +179,8 @@ class blockstore_heap_t void recheck_buffer(heap_entry_t *cwr, uint8_t *buf); void defragment_block(uint32_t block_num); - int allocate_entry(uint32_t entry_size, uint32_t *block_num, heap_entry_t **entry, bool allow_last_free); - int add_entry(uint32_t wr_size, heap_entry_t *old_head, uint32_t *modified_block, bool allow_last_free, + int allocate_entry(uint32_t entry_size, uint32_t *block_num, bool allow_last_free); + int add_entry(uint32_t wr_size, uint32_t *modified_block, bool allow_last_free, std::function fill_entry); int add_simple(heap_entry_t *obj, uint64_t version, uint32_t *modified_block, uint32_t entry_type); uint32_t meta_alloc_pos(const heap_block_info_t & inf); @@ -190,7 +195,8 @@ public: ~blockstore_heap_t(); // load data from the disk, returns EDOM on corruption int read_blocks(uint64_t disk_offset, uint64_t size, uint8_t *buf, - std::function handle_write, std::function handle_block); + std::function handle_write, + std::function handle_block); int load_blocks(uint64_t disk_offset, uint64_t size, uint8_t *buf, uint64_t &entries_loaded); // finish loading void finish_load(); diff --git a/src/test/test_blockstore.cpp b/src/test/test_blockstore.cpp index 3faa975b..29c4fc22 100644 --- a/src/test/test_blockstore.cpp +++ b/src/test/test_blockstore.cpp @@ -427,7 +427,7 @@ static void test_padded_csum_intent(bool perfect) assert(memcheck(op2.buf+32*1024, 0, 96*1024)); obj = test.bs->heap->read_entry((object_id){ .inode = 1, .stripe = 0 }); - assert(!test.bs->heap->prev(obj)); + assert(test.bs->heap->prev(obj) && test.bs->heap->prev(obj)->is_garbage()); free(op.buf); free(op2.buf); diff --git a/src/test/test_heap.cpp b/src/test/test_heap.cpp index a2b7b9f8..c697857d 100644 --- a/src/test/test_heap.cpp +++ b/src/test/test_heap.cpp @@ -25,21 +25,26 @@ static int count_writes(blockstore_heap_t & heap, heap_entry_t *obj) bool check_used_space(blockstore_heap_t & heap, blockstore_disk_t & dsk, uint32_t block_num) { - // FIXME - return true; -/* uint8_t *data = heap.get_meta_block(block_num); + uint8_t *buf = (uint8_t*)malloc_or_die(dsk.meta_block_size); + heap.get_meta_block(block_num, buf); + uint8_t *data = buf; uint8_t *end = data+dsk.meta_block_size; uint32_t used = 0; while (data < end) { heap_entry_t *wr = ((heap_entry_t*)data); - if (!(wr->size & FREE_SPACE_BIT) && !(wr->prev_pos & GARBAGE_BIT)) + if (!(wr->size & FREE_SPACE_BIT) && !wr->is_garbage()) { used += wr->size; } + if (!wr->size) + { + break; + } data += (wr->size & ~FREE_SPACE_BIT); } - return used == heap.get_meta_block_used_space(block_num);*/ + free(buf); + return used == heap.get_meta_block_used_space(block_num); } int _test_do_big_write(blockstore_heap_t & heap, blockstore_disk_t & dsk, uint64_t inode, uint64_t stripe, uint64_t version, uint64_t location, @@ -163,8 +168,8 @@ void test_mvcc(bool csum) assert(count_writes(heap, heap.read_entry(oid)) == 3); // MVCC prevents GC of old entries - //assert(heap.unlock_entry(oid)); - //assert(count_writes(heap, heap.read_entry(oid)) == 1); // Now we unlock it and old entries are GCed + assert(heap.unlock_entry(oid)); + assert(count_writes(heap, heap.read_entry(oid)) == 3); // Now we unlock it and old entries are GCed, but left in the list } printf("OK test_mvcc %s\n", csum ? "csum" : "no_csum"); @@ -279,8 +284,8 @@ void test_defrag_block() uint32_t big_write_size = heap.get_big_entry_size(); uint32_t small_write_size = heap.get_small_entry_size(0, 4096); - assert(big_write_size == 200); - assert(small_write_size == 84); + assert(big_write_size == 180); + assert(small_write_size == 64); uint32_t nwr = 0; bool add = false; if ((dsk.meta_block_size % (big_write_size+small_write_size)) >= big_write_size) @@ -437,7 +442,7 @@ void test_compact(bool csum, bool stable) obj = heap.read_entry(oid); assert(obj); - assert(count_writes(heap, obj) == 1); + assert(count_writes(heap, obj) == (stable ? 3 : 4)); assert(obj->version == 3); bitmap_set(ref_int_bitmap, 8192, 4096, 4096); assert(!memcmp(obj->get_int_bitmap(&heap), ref_int_bitmap, dsk.clean_entry_bitmap_size)); @@ -933,7 +938,7 @@ void test_rollback() obj = heap.read_entry(oid); assert(obj); - assert(count_writes(heap, obj) == 4); + assert(count_writes(heap, obj) == 6); assert(heap.get_to_compact_count() == 1); @@ -1070,8 +1075,8 @@ void test_full_alloc() uint32_t big_write_size = heap.get_big_entry_size(); uint32_t small_write_size = heap.get_small_entry_size(0, 4096); - assert(big_write_size == 192); - assert(small_write_size == 76); + assert(big_write_size == 180); + assert(small_write_size == 64); uint32_t epb = dsk.meta_block_size/big_write_size; for (int j = 0; j < 4; j++) {