/* wmem_test.c * Wireshark Memory Manager Tests * Copyright 2012, Evan Huus * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "wmem.h" #include "wmem_tree-int.h" #include "wmem_allocator.h" #include "wmem_allocator_block.h" #include "wmem_allocator_block_fast.h" #include "wmem_allocator_simple.h" #include "wmem_allocator_strict.h" #include #define STRING_80 "12345678901234567890123456789012345678901234567890123456789012345678901234567890" #define MAX_ALLOC_SIZE (1024*64) #define MAX_SIMULTANEOUS_ALLOCS 1024 #define CONTAINER_ITERS 10000 typedef void (*wmem_verify_func)(wmem_allocator_t *allocator); /* A local copy of wmem_allocator_new that ignores the * WIRESHARK_DEBUG_WMEM_OVERRIDE variable so that test functions are * guaranteed to actually get the allocator type they asked for */ static wmem_allocator_t * wmem_allocator_force_new(const wmem_allocator_type_t type) { wmem_allocator_t *allocator; allocator = wmem_new(NULL, wmem_allocator_t); allocator->type = type; allocator->callbacks = NULL; allocator->in_scope = TRUE; switch (type) { case WMEM_ALLOCATOR_SIMPLE: wmem_simple_allocator_init(allocator); break; case WMEM_ALLOCATOR_BLOCK: wmem_block_allocator_init(allocator); break; case WMEM_ALLOCATOR_BLOCK_FAST: wmem_block_fast_allocator_init(allocator); break; case WMEM_ALLOCATOR_STRICT: wmem_strict_allocator_init(allocator); break; default: g_assert_not_reached(); /* This is necessary to squelch MSVC errors; is there any way to tell it that g_assert_not_reached() never returns? */ return NULL; }; return allocator; } /* A helper for generating pseudo-random strings. Just uses glib's random number * functions to generate 'numbers' in the printable character range. */ static gchar * wmem_test_rand_string(wmem_allocator_t *allocator, gint minlen, gint maxlen) { gchar *str; gint len, i; len = g_random_int_range(minlen, maxlen); /* +1 for null-terminator */ str = (gchar*)wmem_alloc(allocator, len + 1); str[len] = '\0'; for (i=0; i=0; i--) { /* no wmem_realloc0 so just use memset manually */ ptrs[i] = (char *)wmem_realloc(allocator, ptrs[i], 4*len); memset(ptrs[i], 0, 4*len); } for (i=0; i, orig_str); wmem_strict_check_canaries(allocator); orig_str = "TEST123456789"; new_str = wmem_strndup(allocator, orig_str, 6); g_assert_cmpstr(new_str, ==, "TEST12"); g_assert_cmpstr(new_str, <, orig_str); new_str[0] = 'X'; g_assert_cmpstr(new_str, >, orig_str); wmem_strict_check_canaries(allocator); new_str = wmem_strdup_printf(allocator, "abc %s %% %d", "boo", 23); g_assert_cmpstr(new_str, ==, "abc boo % 23"); new_str = wmem_strdup_printf(allocator, "%s", STRING_80); g_assert_cmpstr(new_str, ==, STRING_80); wmem_strict_check_canaries(allocator); new_str = wmem_strconcat(allocator, "ABC", NULL); g_assert_cmpstr(new_str, ==, "ABC"); new_str = wmem_strconcat(allocator, "ABC", "DEF", NULL); g_assert_cmpstr(new_str, ==, "ABCDEF"); wmem_strict_check_canaries(allocator); new_str = wmem_strconcat(allocator, "", "", "ABCDEF", "", "GH", NULL); g_assert_cmpstr(new_str, ==, "ABCDEFGH"); wmem_strict_check_canaries(allocator); split_str = wmem_strsplit(allocator, "A-C", "-", 2); g_assert_cmpstr(split_str[0], ==, "A"); g_assert_cmpstr(split_str[1], ==, "C"); split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 10); g_assert_cmpstr(split_str[0], ==, "aslkf"); g_assert_cmpstr(split_str[1], ==, "asio"); g_assert_cmpstr(split_str[2], ==, "asfj"); g_assert_cmpstr(split_str[3], ==, "as"); split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 4); g_assert_cmpstr(split_str[0], ==, "aslkf"); g_assert_cmpstr(split_str[1], ==, "asio"); g_assert_cmpstr(split_str[2], ==, "-asfj-as--"); wmem_strict_check_canaries(allocator); orig_str = "TeStAsCiIsTrDoWn"; new_str = wmem_ascii_strdown(allocator, orig_str, -1); g_assert_cmpstr(new_str, ==, "testasciistrdown"); wmem_destroy_allocator(allocator); } #define RESOURCE_USAGE_START get_resource_usage(&start_utime, &start_stime) #define RESOURCE_USAGE_END \ get_resource_usage(&end_utime, &end_stime); \ utime_ms = (end_utime - start_utime) * 1000.0; \ stime_ms = (end_stime - start_stime) * 1000.0 /* NOTE: You have to run "wmem_test --verbose" to see results. */ static void wmem_test_stringperf(void) { #define LOOP_COUNT (1 * 1000 * 1000) wmem_allocator_t *allocator; #ifdef _WIN32 char buffer[1]; #endif char **str_ptr = g_new(char *, LOOP_COUNT); char *s_val = "test string"; double d_val = 1000.2; unsigned u_val = 54321; int i_val = -12345; int i; double start_utime, start_stime, end_utime, end_stime, utime_ms, stime_ms; allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { g_snprintf(NULL, 0, "%s", s_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "g_printf_string_upper_bound (via g_snprintf) 1 string: u %.3f ms s %.3f ms", utime_ms, stime_ms); RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { g_snprintf(NULL, 0, "%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "g_printf_string_upper_bound (via g_snprintf) 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { g_snprintf(NULL, 0, "%s%u%3.5f%02d", s_val, u_val, d_val, i_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "g_printf_string_upper_bound (via g_snprintf) mixed args: u %.3f ms s %.3f ms", utime_ms, stime_ms); #ifdef _WIN32 RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { _snprintf_s(buffer, 1, _TRUNCATE, "%s", s_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "_snprintf_s upper bound 1 string: u %.3f ms s %.3f ms", utime_ms, stime_ms); RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { _snprintf_s(buffer, 1, _TRUNCATE, "%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "_snprintf_s upper bound 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { _snprintf_s(buffer, 1, _TRUNCATE, "%s%u%3.5f%02d", s_val, u_val, d_val, i_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "_snprintf_s upper bound mixed args: u %.3f ms s %.3f ms", utime_ms, stime_ms); #endif RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { str_ptr[i] = g_strdup_printf("%s%s", s_val, s_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "g_strdup_printf 2 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); for (i = 0; i < LOOP_COUNT; i++) { g_free(str_ptr[i]); } RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { str_ptr[i] = g_strconcat(s_val, s_val, NULL); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "g_strconcat 2 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); for (i = 0; i < LOOP_COUNT; i++) { g_free(str_ptr[i]); } RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { str_ptr[i] = g_strdup_printf("%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "g_strdup_printf 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); for (i = 0; i < LOOP_COUNT; i++) { g_free(str_ptr[i]); } RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { str_ptr[i] = g_strconcat(s_val, s_val, s_val, s_val, s_val, NULL); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "g_strconcat 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); for (i = 0; i < LOOP_COUNT; i++) { g_free(str_ptr[i]); } RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { wmem_strdup_printf(allocator, "%s%s", s_val, s_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "wmem_strdup_printf 2 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { wmem_strconcat(allocator, s_val, s_val, NULL); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "wmem_strconcat 2 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { wmem_strdup_printf(allocator, "%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "wmem_strdup_printf 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); RESOURCE_USAGE_START; for (i = 0; i < LOOP_COUNT; i++) { wmem_strconcat(allocator, s_val, s_val, s_val, s_val, s_val, NULL); } RESOURCE_USAGE_END; g_test_minimized_result(utime_ms + stime_ms, "wmem_strconcat 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms); wmem_destroy_allocator(allocator); } /* DATA STRUCTURE TESTING FUNCTIONS (/wmem/datastruct/) */ static void wmem_test_array(void) { wmem_allocator_t *allocator; wmem_array_t *array; unsigned int i, j, k; guint32 val, *buf; guint32 vals[8]; guint32 *raw; guint32 lastint; allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); array = wmem_array_new(allocator, sizeof(guint32)); g_assert(array); g_assert(wmem_array_get_count(array) == 0); for (i=0; i 1) { wmem_list_remove(list, GINT_TO_POINTER(i)); i--; } wmem_list_remove(list, GINT_TO_POINTER(CONTAINER_ITERS - 1)); g_assert(wmem_list_count(list) == 0); g_assert(wmem_list_head(list) == NULL); g_assert(wmem_list_tail(list) == NULL); for (i=0; i0; i--) { g_assert(wmem_stack_peek(stack) == GINT_TO_POINTER(i-1)); g_assert(wmem_stack_pop(stack) == GINT_TO_POINTER(i-1)); g_assert(wmem_stack_count(stack) == i-1); } g_assert(wmem_stack_count(stack) == 0); wmem_destroy_stack(stack); wmem_destroy_allocator(allocator); } static void wmem_test_strbuf(void) { wmem_allocator_t *allocator; wmem_strbuf_t *strbuf; int i; char *str; allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); strbuf = wmem_strbuf_new(allocator, "TEST"); g_assert(strbuf); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TEST"); g_assert(wmem_strbuf_get_len(strbuf) == 4); wmem_strbuf_append(strbuf, "FUZZ"); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ"); g_assert(wmem_strbuf_get_len(strbuf) == 8); wmem_strbuf_append_printf(strbuf, "%d%s", 3, "a"); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3a"); g_assert(wmem_strbuf_get_len(strbuf) == 10); wmem_strbuf_append_c(strbuf, 'q'); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq"); g_assert(wmem_strbuf_get_len(strbuf) == 11); wmem_strbuf_append_unichar(strbuf, g_utf8_get_char("\xC2\xA9")); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq\xC2\xA9"); g_assert(wmem_strbuf_get_len(strbuf) == 13); wmem_strbuf_truncate(strbuf, 32); wmem_strbuf_truncate(strbuf, 24); wmem_strbuf_truncate(strbuf, 16); wmem_strbuf_truncate(strbuf, 13); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq\xC2\xA9"); g_assert(wmem_strbuf_get_len(strbuf) == 13); wmem_strbuf_truncate(strbuf, 3); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TES"); g_assert(wmem_strbuf_get_len(strbuf) == 3); strbuf = wmem_strbuf_sized_new(allocator, 10, 10); g_assert(strbuf); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, ""); g_assert(wmem_strbuf_get_len(strbuf) == 0); wmem_strbuf_append(strbuf, "FUZZ"); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ"); g_assert(wmem_strbuf_get_len(strbuf) == 4); wmem_strbuf_append_printf(strbuf, "%d%s", 3, "abcdefghijklmnop"); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd"); g_assert(wmem_strbuf_get_len(strbuf) == 9); wmem_strbuf_append(strbuf, "abcdefghijklmnopqrstuvwxyz"); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd"); g_assert(wmem_strbuf_get_len(strbuf) == 9); wmem_strbuf_append_c(strbuf, 'q'); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd"); g_assert(wmem_strbuf_get_len(strbuf) == 9); wmem_strbuf_append_unichar(strbuf, g_utf8_get_char("\xC2\xA9")); g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd"); g_assert(wmem_strbuf_get_len(strbuf) == 9); str = wmem_strbuf_finalize(strbuf); g_assert_cmpstr(str, ==, "FUZZ3abcd"); g_assert(strlen(str) == 9); wmem_free_all(allocator); strbuf = wmem_strbuf_new(allocator, "TEST"); for (i=0; i<1024; i++) { if (g_test_rand_bit()) { wmem_strbuf_append(strbuf, "ABC"); } else { wmem_strbuf_append_printf(strbuf, "%d%d", 3, 777); } wmem_strict_check_canaries(allocator); } g_assert(strlen(wmem_strbuf_get_str(strbuf)) == wmem_strbuf_get_len(strbuf)); wmem_destroy_allocator(allocator); } static void wmem_test_tree(void) { wmem_allocator_t *allocator, *extra_allocator; wmem_tree_t *tree; guint32 i; int seen_values = 0; int j; gchar *str_key; #define WMEM_TREE_MAX_KEY_COUNT 8 #define WMEM_TREE_MAX_KEY_LEN 4 int key_count; wmem_tree_key_t keys[WMEM_TREE_MAX_KEY_COUNT]; allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); extra_allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); tree = wmem_tree_new(allocator); g_assert(tree); g_assert(wmem_tree_is_empty(tree)); /* test basic 32-bit key operations */ for (i=0; i 0) { g_assert(wmem_tree_lookup32_le(tree, i) == GINT_TO_POINTER(i-1)); } wmem_tree_insert32(tree, i, GINT_TO_POINTER(i)); g_assert(wmem_tree_lookup32(tree, i) == GINT_TO_POINTER(i)); g_assert(!wmem_tree_is_empty(tree)); } g_assert(wmem_tree_count(tree) == CONTAINER_ITERS); wmem_free_all(allocator); tree = wmem_tree_new(allocator); for (i=0; irange)) { d->counter++; } return FALSE; } static gboolean wmem_test_overlap(guint64 low, guint64 high, guint64 lowbis, guint64 highbis) { wmem_range_t r1 = {low, high, 0}; wmem_range_t r2 = {lowbis, highbis, 0}; return wmem_itree_range_overlap(&r1, &r2); } /* wmem_itree_insert_point tests {{{ */ /* expected old data and new data for itree tests. */ static guint64 expectedLeft, expectedRight, itreeNewData; static guint itree_data_callbacks_count; static void setup_itree_expectations(guint64 left, guint64 right, guint64 data) { expectedLeft = left; expectedRight = right; itreeNewData = data; itree_data_callbacks_count = 0; } typedef struct { guint64 low; guint64 high; guint64 value; } wmem_test_itree_node_t; static gboolean wmem_test_itree_nodes_cb(const void *key, void *value, void *userData) { wmem_array_t *arr = (wmem_array_t *)userData; wmem_range_t *range = (wmem_range_t *)key; wmem_test_itree_node_t val; val.low = range->low; val.high = range->high; val.value = GPOINTER_TO_UINT(value); wmem_array_append_one(arr, val); return FALSE; } static wmem_test_itree_node_t * check_itree_nodes(wmem_allocator_t *allocator, wmem_itree_t *tree, guint expected_count) { wmem_array_t *arr; g_assert_cmpuint(wmem_tree_count(tree), ==, expected_count); arr = wmem_array_sized_new(allocator, sizeof(wmem_test_itree_node_t), expected_count); wmem_tree_foreach(tree, wmem_test_itree_nodes_cb, arr); g_assert_cmpuint(wmem_array_get_count(arr), ==, expected_count); return wmem_array_get_raw(arr); } static void check_itree_node(wmem_test_itree_node_t *actual, guint64 low, guint64 high, guint64 value) { g_assert_cmpuint(actual->low, ==, low); g_assert_cmpuint(actual->high, ==, high); g_assert_cmpuint(actual->value, ==, value); } static void * itree_data_callback(void *oldData1, void *oldData2) { g_assert_cmpuint(GPOINTER_TO_UINT(oldData1), ==, expectedLeft); g_assert_cmpuint(GPOINTER_TO_UINT(oldData2), ==, expectedRight); ++itree_data_callbacks_count; return GUINT_TO_POINTER(itreeNewData); } static void * itree_data_unexpected_callback(void *oldData1 _U_, void *oldData2 _U_) { g_assert_not_reached(); return NULL; } static void wmem_test_itree_insert_point(wmem_allocator_t *allocator) { wmem_itree_t *tree; wmem_test_itree_node_t *nodes; tree = wmem_itree_new(allocator); /* new interval (3,3)=101 */ setup_itree_expectations(0, 0, 101); wmem_itree_insert_point(tree, 3, itree_data_callback); g_assert_cmpuint(itree_data_callbacks_count, ==, 1); nodes = check_itree_nodes(allocator, tree, 1); check_itree_node(&nodes[0], 3, 3, 101); /* extend interval (3,3)=101 on the left to (2,3)=102 */ setup_itree_expectations(0, 101, 102); wmem_itree_insert_point(tree, 2, itree_data_callback); g_assert_cmpuint(itree_data_callbacks_count, ==, 1); nodes = check_itree_nodes(allocator, tree, 1); check_itree_node(&nodes[0], 2, 3, 102); /* new interval (0,0)=103 at edge case (left) */ setup_itree_expectations(0, 0, 103); wmem_itree_insert_point(tree, 0, itree_data_callback); g_assert_cmpuint(itree_data_callbacks_count, ==, 1); nodes = check_itree_nodes(allocator, tree, 2); check_itree_node(&nodes[0], 0, 0, 103); check_itree_node(&nodes[1], 2, 3, 102); /* new interval (MAX,MAX)=104 at edge case (right) */ setup_itree_expectations(0, 0, 104); wmem_itree_insert_point(tree, G_MAXUINT64, itree_data_callback); g_assert_cmpuint(itree_data_callbacks_count, ==, 1); nodes = check_itree_nodes(allocator, tree, 3); check_itree_node(&nodes[0], 0, 0, 103); check_itree_node(&nodes[1], 2, 3, 102); check_itree_node(&nodes[2], G_MAXUINT64, G_MAXUINT64, 104); /* must merge two intervals (0,0)=103 and (2,3)=102 into (0,3)=105 */ setup_itree_expectations(103, 102, 105); wmem_itree_insert_point(tree, 1, itree_data_callback); g_assert_cmpuint(itree_data_callbacks_count, ==, 1); nodes = check_itree_nodes(allocator, tree, 2); check_itree_node(&nodes[0], 0, 3, 105); check_itree_node(&nodes[1], G_MAXUINT64, G_MAXUINT64, 104); /* extend interval (0,3)=105 on the right to (0,4)=106 */ setup_itree_expectations(105, 0, 106); wmem_itree_insert_point(tree, 4, itree_data_callback); g_assert_cmpuint(itree_data_callbacks_count, ==, 1); nodes = check_itree_nodes(allocator, tree, 2); check_itree_node(&nodes[0], 0, 4, 106); check_itree_node(&nodes[1], G_MAXUINT64, G_MAXUINT64, 104); /* updating an existing interval (left, middle, right) should not have any effect */ wmem_itree_insert_point(tree, 0, itree_data_unexpected_callback); wmem_itree_insert_point(tree, 1, itree_data_unexpected_callback); wmem_itree_insert_point(tree, 4, itree_data_unexpected_callback); } /* }}} */ static void wmem_test_itree(void) { wmem_allocator_t *allocator, *extra_allocator; wmem_itree_t *tree; int i = 0; gint32 max_rand = 0; wmem_test_itree_user_data_t userData; wmem_range_t range, r2; allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); extra_allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT); tree = wmem_itree_new(allocator); g_assert(tree); g_assert(wmem_itree_is_empty(tree)); wmem_free_all(allocator); /* make sure that wmem_test_overlap is correct (well it's no proof but...)*/ g_assert(wmem_test_overlap(0, 10, 0, 4)); g_assert(wmem_test_overlap(0, 10, 9, 14)); g_assert(wmem_test_overlap(5, 10, 3, 8)); g_assert(wmem_test_overlap(5, 10, 1, 12)); g_assert(!wmem_test_overlap(0, 10, 11, 12)); /* Generate a reference range, then fill an itree with random ranges, then we count greedily the number of overlapping ranges and compare the result with the optimized result */ userData.counter = 0; tree = wmem_itree_new(allocator); /* even though keys are uint64_t, we use G_MAXINT32 as a max because of the type returned by g_test_rand_int_range. */ max_rand = G_MAXINT32; r2.max_edge = range.max_edge = 0; range.low = g_test_rand_int_range(0, max_rand); range.high = g_test_rand_int_range( (gint32)range.low, (gint32)max_rand); userData.range = range; for (i=0; i