diff --git a/src/numeric_range_trie.cpp b/src/numeric_range_trie.cpp index 5b397716..d5f93e36 100644 --- a/src/numeric_range_trie.cpp +++ b/src/numeric_range_trie.cpp @@ -27,51 +27,70 @@ void NumericTrie::search_range(const int32_t& low, const bool& low_inclusive, if (low < 0 && high >= 0) { // Have to combine the results of >low from negative_trie and low from negative_trie. negative_trie->search_less_than(low_inclusive ? abs_low : abs_low - 1, negative_ids, negative_ids_length); + + uint32_t* out = nullptr; + ids_length = ArrayUtils::or_scalar(negative_ids, negative_ids_length, ids, ids_length, &out); + + delete [] negative_ids; + delete [] ids; + ids = out; } - uint32_t* positive_ids = nullptr; - uint32_t positive_ids_length = 0; if (positive_trie != nullptr && !(high == 0 && !high_inclusive)) { // No need to search for ..., 0) + uint32_t* positive_ids = nullptr; + uint32_t positive_ids_length = 0; positive_trie->search_less_than(high_inclusive ? high : high - 1, positive_ids, positive_ids_length); + + uint32_t* out = nullptr; + ids_length = ArrayUtils::or_scalar(positive_ids, positive_ids_length, ids, ids_length, &out); + + delete [] positive_ids; + delete [] ids; + ids = out; } - - ids_length = ArrayUtils::or_scalar(negative_ids, negative_ids_length, positive_ids, positive_ids_length, &ids); - - delete [] negative_ids; - delete [] positive_ids; - return; } else if (low >= 0) { // Search only in positive_trie + if (positive_trie == nullptr) { + return; + } uint32_t* positive_ids = nullptr; uint32_t positive_ids_length = 0; - if (positive_trie != nullptr) { - positive_trie->search_range(low_inclusive ? low : low + 1, high_inclusive ? high : high - 1, - positive_ids, positive_ids_length); - } + positive_trie->search_range(low_inclusive ? low : low + 1, high_inclusive ? high : high - 1, + positive_ids, positive_ids_length); - ids = positive_ids; - ids_length = positive_ids_length; + uint32_t* out = nullptr; + ids_length = ArrayUtils::or_scalar(positive_ids, positive_ids_length, ids, ids_length, &out); + + delete [] positive_ids; + delete [] ids; + ids = out; } else { // Search only in negative_trie + if (negative_trie == nullptr) { + return; + } uint32_t* negative_ids = nullptr; uint32_t negative_ids_length = 0; - if (negative_trie != nullptr) { - // Since we store absolute values, switching low and high would produce the correct result. - auto abs_high = std::abs(high), abs_low = std::abs(low); - negative_trie->search_range(high_inclusive ? abs_high : abs_high + 1, low_inclusive ? abs_low : abs_low - 1, - negative_ids, negative_ids_length); - } + // Since we store absolute values, switching low and high would produce the correct result. + auto abs_high = std::abs(high), abs_low = std::abs(low); + negative_trie->search_range(high_inclusive ? abs_high : abs_high + 1, low_inclusive ? abs_low : abs_low - 1, + negative_ids, negative_ids_length); - ids = negative_ids; - ids_length = negative_ids_length; + uint32_t* out = nullptr; + ids_length = ArrayUtils::or_scalar(negative_ids, negative_ids_length, ids, ids_length, &out); + + delete [] negative_ids; + delete [] ids; + ids = out; } } diff --git a/test/numeric_range_trie_test.cpp b/test/numeric_range_trie_test.cpp index a4e5cb8a..b8ba9186 100644 --- a/test/numeric_range_trie_test.cpp +++ b/test/numeric_range_trie_test.cpp @@ -37,52 +37,51 @@ TEST_F(NumericRangeTrieTest, SearchRange) { uint32_t ids_length = 0; trie->search_range(32768, true, -32768, true, ids, ids_length); - std::unique_ptr ids_guard(ids); ASSERT_EQ(0, ids_length); + reset(ids, ids_length); trie->search_range(-32768, true, 32768, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(pairs.size(), ids_length); for (uint32_t i = 0; i < pairs.size(); i++) { ASSERT_EQ(pairs[i].second, ids[i]); } + reset(ids, ids_length); trie->search_range(-32768, true, 32768, false, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(pairs.size() - 1, ids_length); for (uint32_t i = 0; i < pairs.size() - 1; i++) { ASSERT_EQ(pairs[i].second, ids[i]); } + reset(ids, ids_length); trie->search_range(-32768, true, 134217728, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(pairs.size(), ids_length); for (uint32_t i = 0; i < pairs.size(); i++) { ASSERT_EQ(pairs[i].second, ids[i]); } + reset(ids, ids_length); trie->search_range(-32768, true, 0, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(4, ids_length); for (uint32_t i = 0; i < 4; i++) { ASSERT_EQ(pairs[i].second, ids[i]); } + reset(ids, ids_length); trie->search_range(-32768, true, 0, false, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(4, ids_length); for (uint32_t i = 0; i < 4; i++) { ASSERT_EQ(pairs[i].second, ids[i]); } + reset(ids, ids_length); trie->search_range(-32768, false, 32768, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(pairs.size() - 1, ids_length); for (uint32_t i = 0, j = 0; i < pairs.size(); i++) { @@ -90,93 +89,97 @@ TEST_F(NumericRangeTrieTest, SearchRange) { ASSERT_EQ(pairs[i].second, ids[j++]); } + reset(ids, ids_length); trie->search_range(-134217728, true, 32768, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(pairs.size(), ids_length); for (uint32_t i = 0; i < pairs.size(); i++) { ASSERT_EQ(pairs[i].second, ids[i]); } + reset(ids, ids_length); trie->search_range(-134217728, true, 134217728, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(pairs.size(), ids_length); for (uint32_t i = 0; i < pairs.size(); i++) { ASSERT_EQ(pairs[i].second, ids[i]); } + reset(ids, ids_length); trie->search_range(-1, true, 32768, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(4, ids_length); for (uint32_t i = 4, j = 0; i < pairs.size(); i++, j++) { ASSERT_EQ(pairs[i].second, ids[j]); } + reset(ids, ids_length); trie->search_range(-1, false, 32768, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(4, ids_length); for (uint32_t i = 4, j = 0; i < pairs.size(); i++, j++) { ASSERT_EQ(pairs[i].second, ids[j]); } + reset(ids, ids_length); trie->search_range(-1, true, 0, true, ids, ids_length); ASSERT_EQ(0, ids_length); + reset(ids, ids_length); trie->search_range(-1, false, 0, false, ids, ids_length); ASSERT_EQ(0, ids_length); + reset(ids, ids_length); trie->search_range(8192, true, 32768, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(4, ids_length); for (uint32_t i = 4, j = 0; i < ids_length; i++, j++) { ASSERT_EQ(pairs[i].second, ids[j]); } + reset(ids, ids_length); trie->search_range(8192, true, 0x2000000, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(4, ids_length); for (uint32_t i = 4, j = 0; i < ids_length; i++, j++) { ASSERT_EQ(pairs[i].second, ids[j]); } + reset(ids, ids_length); trie->search_range(16384, true, 16384, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(1, ids_length); ASSERT_EQ(56, ids[0]); + reset(ids, ids_length); trie->search_range(16384, true, 16384, false, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(0, ids_length); + reset(ids, ids_length); trie->search_range(16384, false, 16384, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(0, ids_length); + reset(ids, ids_length); trie->search_range(16383, true, 16383, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(0, ids_length); + reset(ids, ids_length); trie->search_range(8193, true, 16383, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(0, ids_length); + reset(ids, ids_length); trie->search_range(-32768, true, -8192, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(4, ids_length); for (uint32_t i = 0; i < ids_length; i++) { ASSERT_EQ(pairs[i].second, ids[i]); } + + reset(ids, ids_length); } TEST_F(NumericRangeTrieTest, SearchGreaterThan) { @@ -439,7 +442,6 @@ TEST_F(NumericRangeTrieTest, MultivalueData) { uint32_t ids_length = 0; trie->search_less_than(0, false, ids, ids_length); - std::unique_ptr ids_guard(ids); std::vector expected = {5, 8, 32, 35, 43}; @@ -448,8 +450,8 @@ TEST_F(NumericRangeTrieTest, MultivalueData) { ASSERT_EQ(expected[i], ids[i]); } + reset(ids, ids_length); trie->search_less_than(-16380, false, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(4, ids_length); @@ -458,8 +460,8 @@ TEST_F(NumericRangeTrieTest, MultivalueData) { ASSERT_EQ(expected[i], ids[i]); } + reset(ids, ids_length); trie->search_less_than(16384, false, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(7, ids_length); @@ -468,8 +470,8 @@ TEST_F(NumericRangeTrieTest, MultivalueData) { ASSERT_EQ(expected[i], ids[i]); } + reset(ids, ids_length); trie->search_greater_than(0, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(7, ids_length); @@ -478,8 +480,8 @@ TEST_F(NumericRangeTrieTest, MultivalueData) { ASSERT_EQ(expected[i], ids[i]); } + reset(ids, ids_length); trie->search_greater_than(256, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(5, ids_length); @@ -488,8 +490,8 @@ TEST_F(NumericRangeTrieTest, MultivalueData) { ASSERT_EQ(expected[i], ids[i]); } + reset(ids, ids_length); trie->search_greater_than(-32768, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(9, ids_length); @@ -498,8 +500,8 @@ TEST_F(NumericRangeTrieTest, MultivalueData) { ASSERT_EQ(expected[i], ids[i]); } + reset(ids, ids_length); trie->search_range(-32768, true, 0, true, ids, ids_length); - ids_guard.reset(ids); ASSERT_EQ(6, ids_length); @@ -507,6 +509,8 @@ TEST_F(NumericRangeTrieTest, MultivalueData) { for (uint32_t i = 0; i < ids_length; i++) { ASSERT_EQ(expected[i], ids[i]); } + + reset(ids, ids_length); } TEST_F(NumericRangeTrieTest, EmptyTrieOperations) {