#include #include "interval_tree.h" struct interval_tree_node *node_new(uint64_t start, uint64_t last, void *user_data) { uint64_t size = last - start + 1; struct interval_tree_node *node = (struct interval_tree_node *)calloc(1, sizeof(struct interval_tree_node) + size); if (node == nullptr) { return nullptr; } node->start = start; node->last = last; node->user_data = (char *)node + sizeof(struct interval_tree_node); memcpy(node->user_data, user_data, size); printf("new node: %p, start: %lu, last: %lu, user_data: %s\n", node, node->start, node->last, (char *)node->user_data); return node; } void node_free(struct interval_tree_node *node) { if (node) { printf("free node: %p, start: %lu, last: %lu, user_data: %s\n", node, node->start, node->last, (char *)node->user_data); free(node); node = NULL; } } struct range { uint64_t start; uint64_t last; }; #if 1 TEST(INTERVAL_TREE, FIND) { struct rb_root_cached root = RB_ROOT_CACHED; struct interval_tree_node *node; // insert node = node_new(5, 10, (void *)"Hello"); interval_tree_insert(node, &root); // not found struct range ranges_not_found[] = { {0, 4}, {11, 15}, }; for (size_t i = 0; i < sizeof(ranges_not_found) / sizeof(ranges_not_found[0]); i++) { node = interval_tree_iter_first(&root, ranges_not_found[i].start, ranges_not_found[i].last); EXPECT_TRUE(node == nullptr); } // found struct range ranges_found[] = { // overlap interval {0, 5}, {1, 6}, {2, 7}, {3, 8}, {4, 9}, {5, 10}, {6, 11}, {7, 12}, {8, 13}, {9, 14}, {10, 15}, // overlap point {5, 5}, {6, 6}, {7, 7}, {8, 8}, {9, 9}, {10, 10}, // overlap interval {5, 10}, {4, 11}, }; for (size_t i = 0; i < sizeof(ranges_found) / sizeof(ranges_found[0]); i++) { node = interval_tree_iter_first(&root, ranges_found[i].start, ranges_found[i].last); EXPECT_TRUE(node != nullptr); EXPECT_TRUE(node->start == 5); EXPECT_TRUE(node->last == 10); EXPECT_STREQ((const char *)node->user_data, "Hello"); } // remove interval_tree_remove(node, &root); node_free(node); // find node = interval_tree_iter_first(&root, 5, 10); EXPECT_TRUE(node == nullptr); } #endif #if 1 TEST(INTERVAL_TREE, REPEAT) { struct rb_root_cached root = RB_ROOT_CACHED; struct interval_tree_node *node; // insert node = node_new(5, 10, (void *)"Hello"); interval_tree_insert(node, &root); // insert repeat node = node_new(5, 10, (void *)"World"); interval_tree_insert(node, &root); node = interval_tree_iter_first(&root, 5, 10); EXPECT_TRUE(node != nullptr); EXPECT_TRUE(node->start == 5); EXPECT_TRUE(node->last == 10); EXPECT_STREQ((const char *)node->user_data, "Hello"); node = interval_tree_iter_next(node, 5, 10); EXPECT_TRUE(node != nullptr); EXPECT_TRUE(node->start == 5); EXPECT_TRUE(node->last == 10); EXPECT_STREQ((const char *)node->user_data, "World"); node = interval_tree_iter_next(node, 5, 10); EXPECT_TRUE(node == nullptr); // remove all while ((node = interval_tree_iter_first(&root, 5, 10)) != nullptr) { interval_tree_remove(node, &root); node_free(node); } } #endif #if 1 TEST(INTERVAL_TREE, OVERLAP) { struct rb_root_cached root = RB_ROOT_CACHED; struct interval_tree_node *node; // insert node = node_new(5, 10, (void *)"Hello"); interval_tree_insert(node, &root); // insert repeat node = node_new(7, 12, (void *)"World"); interval_tree_insert(node, &root); node = interval_tree_iter_first(&root, 5, 10); EXPECT_TRUE(node != nullptr); EXPECT_TRUE(node->start == 5); EXPECT_TRUE(node->last == 10); EXPECT_STREQ((const char *)node->user_data, "Hello"); node = interval_tree_iter_next(node, 5, 10); EXPECT_TRUE(node != nullptr); EXPECT_TRUE(node->start == 7); EXPECT_TRUE(node->last == 12); EXPECT_STREQ((const char *)node->user_data, "World"); node = interval_tree_iter_next(node, 5, 10); EXPECT_TRUE(node == nullptr); // remove all while ((node = interval_tree_iter_first(&root, 5, 10)) != nullptr) { interval_tree_remove(node, &root); node_free(node); } } #endif int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }