Skip to content

Commit 9a0e504

Browse files
authored
Merge pull request #10 from 5cript/overlap_issue_tests
Overlap issue fixed
2 parents 05f9302 + c3ecba2 commit 9a0e504

File tree

4 files changed

+101
-39
lines changed

4 files changed

+101
-39
lines changed

interval_tree.hpp

+10-36
Original file line numberDiff line numberDiff line change
@@ -1125,22 +1125,15 @@ namespace lib_interval_tree
11251125
if (ptr->left_ && ival.high() <= ptr->left_->max())
11261126
{
11271127
// no right? can only continue left
1128-
if (!ptr->right_)
1129-
return find_all_i<IteratorT>(ptr->left_, ival, on_find, compare);
1130-
1131-
// upper bounds higher than what is contained right? continue left
1132-
if (ival.high() > ptr->right_->max())
1128+
if (!ptr->right_ || ival.low() > ptr->right_->max())
11331129
return find_all_i<IteratorT>(ptr->left_, ival, on_find, compare);
11341130

11351131
if (!find_all_i<IteratorT>(ptr->left_, ival, on_find, compare))
11361132
return false;
11371133
}
11381134
if (ptr->right_ && ival.high() <= ptr->right_->max())
11391135
{
1140-
if (!ptr->left_)
1141-
return find_all_i<IteratorT>(ptr->right_, ival, on_find, compare);
1142-
1143-
if (ival.high() > ptr->left_->max())
1136+
if (!ptr->left_ || ival.low() > ptr->left_->max())
11441137
return find_all_i<IteratorT>(ptr->right_, ival, on_find, compare);
11451138

11461139
if (!find_all_i<IteratorT>(ptr->right_, ival, on_find, compare))
@@ -1165,11 +1158,7 @@ namespace lib_interval_tree
11651158
if (ptr->left_ && ival.high() <= ptr->left_->max())
11661159
{
11671160
// no right? can only continue left
1168-
if (!ptr->right_)
1169-
return find_i(ptr->left_, ival, compare);
1170-
1171-
// upper bounds higher than what is contained right? continue left
1172-
if (ival.high() > ptr->right_->max())
1161+
if (!ptr->right_ || ival.low() > ptr->right_->max())
11731162
return find_i(ptr->left_, ival, compare);
11741163

11751164
auto* res = find_i(ptr->left_, ival, compare);
@@ -1178,10 +1167,7 @@ namespace lib_interval_tree
11781167
}
11791168
if (ptr->right_ && ival.high() <= ptr->right_->max())
11801169
{
1181-
if (!ptr->left_)
1182-
return find_i(ptr->right_, ival, compare);
1183-
1184-
if (ival.high() > ptr->left_->max())
1170+
if (!ptr->left_ || ival.low() > ptr->left_->max())
11851171
return find_i(ptr->right_, ival, compare);
11861172

11871173
auto* res = find_i(ptr->right_, ival, compare);
@@ -1242,22 +1228,16 @@ namespace lib_interval_tree
12421228
if (ptr->left_ && ptr->left_->max() >= ival.low())
12431229
{
12441230
// no right? can only continue left
1245-
if (!ptr->right_)
1246-
return overlap_find_all_i<Exclusive, IteratorT>(ptr->left_, ival, on_find);
1247-
1248-
// upper bounds higher than what is contained right? continue left
1249-
if (ival.high() > ptr->right_->max())
1231+
// or interval low is bigger than max of right branch.
1232+
if (!ptr->right_ || ival.low() > ptr->right_->max())
12501233
return overlap_find_all_i<Exclusive, IteratorT>(ptr->left_, ival, on_find);
12511234

12521235
if (!overlap_find_all_i<Exclusive, IteratorT>(ptr->left_, ival, on_find))
12531236
return false;
12541237
}
12551238
if (ptr->right_ && ptr->right_->max() >= ival.low())
12561239
{
1257-
if (!ptr->left_)
1258-
return overlap_find_all_i<Exclusive, IteratorT>(ptr->right_, ival, on_find);
1259-
1260-
if (ival.high() > ptr->left_->max())
1240+
if (!ptr->left_ || ival.low() > ptr->right_->max())
12611241
return overlap_find_all_i<Exclusive, IteratorT>(ptr->right_, ival, on_find);
12621242

12631243
if (!overlap_find_all_i<Exclusive, IteratorT>(ptr->right_, ival, on_find))
@@ -1273,11 +1253,8 @@ namespace lib_interval_tree
12731253
if (ptr->left_ && ptr->left_->max() >= ival.low())
12741254
{
12751255
// no right? can only continue left
1276-
if (!ptr->right_)
1277-
return overlap_find_i<Exclusive>(ptr->left_, ival);
1278-
1279-
// upper bounds higher than what is contained right? continue left
1280-
if (ival.high() > ptr->right_->max())
1256+
// or upper bounds higher than what is contained right? continue left.
1257+
if (!ptr->right_ || ival.low() > ptr->right_->max())
12811258
return overlap_find_i<Exclusive>(ptr->left_, ival);
12821259

12831260
auto* res = overlap_find_i<Exclusive>(ptr->left_, ival);
@@ -1286,10 +1263,7 @@ namespace lib_interval_tree
12861263
}
12871264
if (ptr->right_ && ptr->right_->max() >= ival.low())
12881265
{
1289-
if (!ptr->left_)
1290-
return overlap_find_i<Exclusive>(ptr->right_, ival);
1291-
1292-
if (ival.high() > ptr->left_->max())
1266+
if (!ptr->left_ || ival.low() > ptr->left_->max())
12931267
return overlap_find_i<Exclusive>(ptr->right_, ival);
12941268

12951269
auto* res = overlap_find_i<Exclusive>(ptr->right_, ival);

tests/find_tests.hpp

+23
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
#pragma once
22

3+
#include <ctime>
4+
#include <random>
5+
#include <cmath>
6+
37
class FindTests
48
: public ::testing::Test
59
{
610
public:
711
using types = IntervalTypes <int>;
812
protected:
913
IntervalTypes <int>::tree_type tree;
14+
std::default_random_engine gen;
15+
std::uniform_int_distribution <int> distLarge{-50000, 50000};
1016
};
1117

1218
TEST_F(FindTests, WillReturnEndIfTreeIsEmpty)
@@ -78,3 +84,20 @@ TEST_F(FindTests, WillFindAllCanExitPreemptively)
7884
EXPECT_EQ(findCount, 3);
7985
}
8086

87+
TEST_F(FindTests, CanFindAllElementsBack)
88+
{
89+
constexpr int amount = 10'000;
90+
91+
std::vector <decltype(tree)::interval_type> intervals;
92+
intervals.reserve(amount);
93+
for (int i = 0; i != amount; ++i)
94+
{
95+
const auto interval = lib_interval_tree::make_safe_interval(distLarge(gen), distLarge(gen));
96+
intervals.emplace_back(interval);
97+
tree.insert(interval);
98+
}
99+
for (auto const& ival : intervals)
100+
{
101+
ASSERT_NE(tree.find(ival), std::end(tree));
102+
}
103+
}

tests/float_overlap_tests.hpp

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#pragma once
2+
3+
#include "test_utility.hpp"
4+
5+
#include <algorithm>
6+
7+
class FloatOverlapFindTests
8+
: public ::testing::Test
9+
{
10+
public:
11+
using types = IntervalTypes <double>;
12+
protected:
13+
IntervalTypes <double>::tree_type tree;
14+
};
15+
16+
TEST_F(FloatOverlapFindTests, FloatOverlapTest)
17+
{
18+
tree.insert(lib_interval_tree::make_safe_interval<double>(-1.483529864195180e+00, -1.296053859335657e+00));
19+
tree.insert(lib_interval_tree::make_safe_interval<double>(-1.308996938995747e+00, -1.127801743538376e+00));
20+
tree.insert(lib_interval_tree::make_safe_interval<double>(-1.134464013796314e+00, -9.562870818388700e-01));
21+
tree.insert(lib_interval_tree::make_safe_interval<double>(-9.599310885968813e-01, -7.834918877708545e-01));
22+
tree.insert(lib_interval_tree::make_safe_interval<double>(-7.853981633974484e-01, -6.090750919515169e-01));
23+
tree.insert(lib_interval_tree::make_safe_interval<double>(-6.108652381980154e-01, -4.348738075675338e-01));
24+
tree.insert(lib_interval_tree::make_safe_interval<double>(-4.363323129985824e-01, -2.608478200480425e-01));
25+
tree.insert(lib_interval_tree::make_safe_interval<double>(-2.617993877991495e-01, -8.693606119038631e-02));
26+
tree.insert(lib_interval_tree::make_safe_interval<double>(-8.726646259971654e-02, 8.726646259971654e-02));
27+
tree.insert(lib_interval_tree::make_safe_interval<double>(8.693606119038631e-02, 2.617993877991493e-01));
28+
tree.insert(lib_interval_tree::make_safe_interval<double>(2.608478200480422e-01, 4.363323129985823e-01));
29+
tree.insert(lib_interval_tree::make_safe_interval<double>(4.348738075675337e-01, 6.108652381980154e-01));
30+
tree.insert(lib_interval_tree::make_safe_interval<double>(6.090750919515169e-01, 7.853981633974484e-01));
31+
tree.insert(lib_interval_tree::make_safe_interval<double>(7.834918877708545e-01, 9.599310885968813e-01));
32+
tree.insert(lib_interval_tree::make_safe_interval<double>(9.562870818388700e-01, 1.134464013796314e+00)); //
33+
tree.insert(lib_interval_tree::make_safe_interval<double>(1.127801743538376e+00, 1.308996938995747e+00)); //
34+
tree.insert(lib_interval_tree::make_safe_interval<double>(1.296053859335657e+00, 1.483529864195180e+00)); //
35+
36+
double lat0 = 1.040893537045970;
37+
double lat1 = 1.570796326794897;
38+
39+
std::vector <std::pair<double, double>> vecOverlapsA;
40+
lib_interval_tree::interval <double> intSource({lat0, lat1});
41+
for (auto const& iter : tree)
42+
{
43+
if (iter.overlaps(intSource))
44+
vecOverlapsA.push_back({iter.low(), iter.high()});
45+
}
46+
47+
std::vector <std::pair<double, double>> vecOverlapsB;
48+
tree.overlap_find_all
49+
(
50+
{lat0, lat1},
51+
[&vecOverlapsB](lib_interval_tree::interval_tree_t<double>::iterator iter)
52+
{
53+
vecOverlapsB.push_back({iter->low(), iter->high()});
54+
return true;
55+
},
56+
false
57+
);
58+
59+
std::sort(std::begin(vecOverlapsA), std::end(vecOverlapsA));
60+
std::sort(std::begin(vecOverlapsB), std::end(vecOverlapsB));
61+
62+
ASSERT_EQ(vecOverlapsA.size(), vecOverlapsB.size());
63+
EXPECT_THAT(vecOverlapsA, ::testing::ContainerEq(vecOverlapsB));
64+
}

tests/tests.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33

44
#include "../interval_tree.hpp"
55
#include "typedefs.hpp"
6-
#include "example_drawings.hpp"
6+
//#include "example_drawings.hpp"
77

88
// following headers expect to be included after gtest headers and interval_tree
99
#include "interval_tests.hpp"
1010
#include "insert_tests.hpp"
1111
#include "erase_tests.hpp"
1212
#include "find_tests.hpp"
13-
#include "overlap_find_tests.hpp"
14-
13+
#include "overlap_find_tests.hpp"
14+
#include "float_overlap_tests.hpp"
15+
1516
int main(int argc, char** argv)
1617
{
1718
#ifdef INTERVAL_TREE_DO_DRAWINGS

0 commit comments

Comments
 (0)