From fe2d01c3728a01fcadb38852d04a322f92c9f7eb Mon Sep 17 00:00:00 2001 From: Zachary Dremann Date: Sat, 20 Jan 2024 11:47:03 -0500 Subject: [PATCH] Move test for node48 into `art_unit` --- tests/art_unit.cpp | 66 ++++++++++++++++++++++++++++++++++------ tests/roaring64_unit.cpp | 22 -------------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/tests/art_unit.cpp b/tests/art_unit.cpp index 56355d6f1..09ccab00e 100644 --- a/tests/art_unit.cpp +++ b/tests/art_unit.cpp @@ -1,11 +1,10 @@ #include #include -#include #include +#include #include #include -#include #include #include #include @@ -17,13 +16,13 @@ using namespace roaring::internal; namespace { -void print_key(art_key_chunk_t* key) { +void print_key(const art_key_chunk_t* key) { for (size_t i = 0; i < ART_KEY_BYTES; ++i) { printf("%x", *(key + i)); } } -void assert_key_eq(art_key_chunk_t* key1, art_key_chunk_t* key2) { +void assert_key_eq(const art_key_chunk_t* key1, const art_key_chunk_t* key2) { for (size_t i = 0; i < ART_KEY_BYTES; ++i) { if (*(key1 + i) != *(key2 + i)) { print_key(key1); @@ -39,8 +38,7 @@ void assert_key_eq(art_key_chunk_t* key1, art_key_chunk_t* key2) { class Key { public: Key(uint64_t key) { - // Reverse byte order of the low 6 bytes. Not portable to big-endian - // systems! + // Store the low 6 bytes of the key in big-endian order. key_[0] = key >> 40 & 0xFF; key_[1] = key >> 32 & 0xFF; key_[2] = key >> 24 & 0xFF; @@ -49,7 +47,7 @@ class Key { key_[5] = key >> 0 & 0xFF; } - Key(uint8_t* key) { + Key(const uint8_t* key) { for (size_t i = 0; i < 6; ++i) { key_[i] = *(key + i); } @@ -78,9 +76,9 @@ class Key { struct Value : art_val_t { Value() {} Value(uint64_t val_) : val(val_) {} - bool operator==(const Value& other) { return val == other.val; } + bool operator==(const Value& other) const { return val == other.val; } - uint64_t val; + uint64_t val = 0; }; class ShadowedART { @@ -121,7 +119,7 @@ class ShadowedART { break; } if (found_val->val != value.val) { - printf("Key %s: ART value %lu != shadow value %lu\n", + printf("Key %s: ART value %" PRIu64 " != shadow value %" PRIu64 "\n", key.string().c_str(), found_val->val, value.val); assert_true(*found_val == value); break; @@ -440,6 +438,53 @@ DEFINE_TEST(test_art_shadowed) { art.assertLowerBoundValid(1); } +DEFINE_TEST(test_art_shrink_grow_node48) { + art_t art{nullptr}; + std::vector values(48); + // Make a full node48. + for (int i = 0; i < 48; i++) { + auto key = Key(i); + values[i].val = i; + art_insert(&art, key.data(), &values[i]); + } + // Remove the first several containers + for (int i = 0; i < 8; i++) { + auto key = Key(i); + Value *removed_val = (Value *)(art_erase(&art, key.data())); + assert_int_equal(removed_val->val, i); + } + { + art_iterator_t iterator = art_init_iterator(&art, true); + int i = 8; + do { + auto key = Key(i); + assert_key_eq(iterator.key, key.data()); + assert_true(iterator.value == &values[i]); + ++i; + } while (art_iterator_next(&iterator)); + assert_int_equal(i, 48); + } + + // Fill the containers back up + for (int i = 0; i < 8; i++) { + auto key = Key(i); + values[i].val = i; + art_insert(&art, key.data(), &values[i]); + } + { + art_iterator_t iterator = art_init_iterator(&art, true); + int i = 0; + do { + auto key = Key(i); + assert_key_eq(iterator.key, key.data()); + assert_true(iterator.value == &values[i]); + ++i; + } while (art_iterator_next(&iterator)); + assert_int_equal(i, 48); + } + art_free(&art); +} + } // namespace int main() { @@ -455,6 +500,7 @@ int main() { cmocka_unit_test(test_art_iterator_erase), cmocka_unit_test(test_art_iterator_insert), cmocka_unit_test(test_art_shadowed), + cmocka_unit_test(test_art_shrink_grow_node48), }; return cmocka_run_group_tests(tests, NULL, NULL); } diff --git a/tests/roaring64_unit.cpp b/tests/roaring64_unit.cpp index ac7a0ad64..8a8a78b11 100644 --- a/tests/roaring64_unit.cpp +++ b/tests/roaring64_unit.cpp @@ -952,27 +952,6 @@ DEFINE_TEST(test_andnot_inplace) { } } -DEFINE_TEST(test_shrink_grow_48_art_node) { - roaring64_bitmap_t* r1 = roaring64_bitmap_create(); - - uint64_t lo = 0; - uint64_t mi = 8 * 0x10000; - uint64_t hi = 47 * 0x10000; - - // ART root should be a full 48 item node - roaring64_bitmap_add_range_closed(r1, lo, hi); - // First several items removed - roaring64_bitmap_remove_range_closed(r1, lo, mi); - // Adding back the item with key 0 - roaring64_bitmap_add(r1, 0); - - uint64_t expected_card = (hi + 1) - (mi + 1) + 1; - - assert_int_equal(roaring64_bitmap_get_cardinality(r1), expected_card); - - roaring64_bitmap_free(r1); -} - bool roaring_iterator64_sumall(uint64_t value, void* param) { *(uint64_t*)param += value; return true; @@ -1305,7 +1284,6 @@ int main() { cmocka_unit_test(test_andnot), cmocka_unit_test(test_andnot_cardinality), cmocka_unit_test(test_andnot_inplace), - cmocka_unit_test(test_shrink_grow_48_art_node), cmocka_unit_test(test_iterate), cmocka_unit_test(test_iterator_create), cmocka_unit_test(test_iterator_create_last),