3
3
#include < ctime>
4
4
#include < random>
5
5
#include < cmath>
6
+ #include < iostream>
7
+
8
+ struct Oracle
9
+ {
10
+ int livingInstances = 0 ;
11
+ };
12
+
13
+ template <typename numerical_type, typename interval_kind_ = lib_interval_tree::closed>
14
+ class OracleInterval : public lib_interval_tree ::interval<numerical_type, interval_kind_>
15
+ {
16
+ public:
17
+ using lib_interval_tree::interval<numerical_type, interval_kind_>::low_;
18
+ using lib_interval_tree::interval<numerical_type, interval_kind_>::high_;
19
+
20
+ OracleInterval (Oracle* oracle, numerical_type start, numerical_type end)
21
+ : lib_interval_tree::interval<numerical_type, interval_kind_>(start, end)
22
+ , oracle_{oracle}
23
+ {
24
+ ++oracle_->livingInstances ;
25
+ }
26
+ OracleInterval (OracleInterval const & other)
27
+ : lib_interval_tree::interval<numerical_type, interval_kind_>(other.low_, other.high_)
28
+ , oracle_{other.oracle_ }
29
+ {
30
+ ++oracle_->livingInstances ;
31
+ }
32
+ OracleInterval (OracleInterval&& other)
33
+ : lib_interval_tree::interval<numerical_type, interval_kind_>(other.low_, other.high_)
34
+ , oracle_{other.oracle_ }
35
+ {
36
+ other.oracle_ = nullptr ;
37
+ }
38
+ OracleInterval& operator =(OracleInterval const & other)
39
+ {
40
+ lib_interval_tree::interval<numerical_type, interval_kind_>::operator =(other);
41
+ oracle_ = other.oracle_ ;
42
+ return *this ;
43
+ }
44
+ OracleInterval& operator =(OracleInterval&& other)
45
+ {
46
+ lib_interval_tree::interval<numerical_type, interval_kind_>::operator =(other);
47
+ oracle_ = other.oracle_ ;
48
+ other.oracle_ = nullptr ;
49
+ return *this ;
50
+ }
51
+ ~OracleInterval ()
52
+ {
53
+ if (oracle_ != nullptr )
54
+ --oracle_->livingInstances ;
55
+ }
56
+ OracleInterval join (OracleInterval const & other) const
57
+ {
58
+ return OracleInterval{oracle_, std::min (low_, other.low_ ), std::max (high_, other.high_ )};
59
+ }
60
+ private:
61
+ Oracle* oracle_;
62
+ };
63
+
64
+ template <typename numerical_type, typename interval_kind_ = lib_interval_tree::closed>
65
+ OracleInterval <numerical_type, interval_kind_> makeSafeOracleInterval (Oracle* oracle, numerical_type lhs, numerical_type rhs)
66
+ {
67
+ return OracleInterval <numerical_type, interval_kind_>{oracle, std::min (lhs, rhs), std::max (lhs, rhs)};
68
+ }
6
69
7
70
class EraseTests
8
71
: public ::testing::Test
9
72
{
10
73
public:
11
- using types = IntervalTypes <int >;
74
+ using interval_type = OracleInterval <int >;
12
75
13
76
protected:
14
- IntervalTypes <int >::tree_type tree;
77
+ Oracle oracle;
78
+ lib_interval_tree::interval_tree <OracleInterval<int >> tree;
15
79
std::default_random_engine gen;
16
80
std::uniform_int_distribution <int > distSmall{-500 , 500 };
17
81
std::uniform_int_distribution <int > distLarge{-50000 , 50000 };
18
82
};
19
83
20
84
TEST_F (EraseTests, EraseSingleElement)
21
85
{
22
- auto inserted_interval = types:: interval_type{0 , 16 };
86
+ auto inserted_interval = interval_type{&oracle, 0 , 16 };
23
87
24
- tree.insert (inserted_interval);
88
+ tree.insert (std::move ( inserted_interval) );
25
89
90
+ EXPECT_EQ (oracle.livingInstances , 1 );
26
91
tree.erase (tree.begin ());
27
92
93
+ EXPECT_EQ (oracle.livingInstances , 0 );
28
94
EXPECT_EQ (tree.empty (), true );
29
95
EXPECT_EQ (tree.size (), 0 );
30
96
}
@@ -34,11 +100,12 @@ TEST_F(EraseTests, ManualClearTest)
34
100
constexpr int amount = 10'000 ;
35
101
36
102
for (int i = 0 ; i != amount; ++i)
37
- tree.insert (lib_interval_tree::make_safe_interval ( distSmall (gen), distSmall (gen)));
103
+ tree.insert (makeSafeOracleInterval (&oracle, distSmall (gen), distSmall (gen)));
38
104
39
105
for (auto i = std::begin (tree); i != std::end (tree);)
40
106
i = tree.erase (i);
41
107
108
+ EXPECT_EQ (oracle.livingInstances , 0 );
42
109
EXPECT_EQ (tree.empty (), true );
43
110
}
44
111
@@ -47,20 +114,39 @@ TEST_F(EraseTests, ClearTest)
47
114
constexpr int amount = 10'000 ;
48
115
49
116
for (int i = 0 ; i != amount; ++i)
50
- tree.insert (lib_interval_tree::make_safe_interval ( distSmall (gen), distSmall (gen)));
117
+ tree.insert (makeSafeOracleInterval (&oracle, distSmall (gen), distSmall (gen)));
51
118
52
119
tree.clear ();
53
120
121
+ EXPECT_EQ (oracle.livingInstances , 0 );
54
122
EXPECT_EQ (tree.empty (), true );
55
123
}
56
124
125
+ TEST_F (EraseTests, ExpectedElementIsDeleted)
126
+ {
127
+ tree.insert (makeSafeOracleInterval (&oracle, 16 , 21 ));
128
+ tree.insert (makeSafeOracleInterval (&oracle, 8 , 9 ));
129
+ tree.insert (makeSafeOracleInterval (&oracle, 25 , 30 ));
130
+ tree.insert (makeSafeOracleInterval (&oracle, 5 , 8 ));
131
+ tree.insert (makeSafeOracleInterval (&oracle, 15 , 23 ));
132
+ tree.insert (makeSafeOracleInterval (&oracle, 17 , 19 ));
133
+ tree.insert (makeSafeOracleInterval (&oracle, 26 , 26 ));
134
+ tree.insert (makeSafeOracleInterval (&oracle, 0 , 3 ));
135
+ tree.insert (makeSafeOracleInterval (&oracle, 6 , 10 ));
136
+ tree.insert (makeSafeOracleInterval (&oracle, 19 , 20 ));
137
+
138
+ tree.erase (tree.find (makeSafeOracleInterval (&oracle, 17 , 19 )));
139
+ EXPECT_EQ (tree.find (makeSafeOracleInterval (&oracle, 17 , 19 )), tree.end ());
140
+ EXPECT_EQ (tree.size (), 9 );
141
+ }
142
+
57
143
TEST_F (EraseTests, RandomEraseTest)
58
144
{
59
145
constexpr int amount = 10'000 ;
60
- constexpr int deleteAmount = 20 ;
146
+ constexpr int deleteAmount = 50 ;
61
147
62
148
for (int i = 0 ; i != amount; ++i)
63
- tree.insert (lib_interval_tree::make_safe_interval ( distSmall (gen), distSmall (gen)));
149
+ tree.insert (makeSafeOracleInterval (&oracle, distSmall (gen), distSmall (gen)));
64
150
65
151
for (int i = 0 ; i != deleteAmount; ++i)
66
152
{
@@ -69,9 +155,10 @@ TEST_F(EraseTests, RandomEraseTest)
69
155
auto iter = tree.begin ();
70
156
for (int j = 0 ; j != end; ++j)
71
157
++iter;
158
+ tree.erase (iter);
72
159
}
73
160
161
+ EXPECT_EQ (oracle.livingInstances , amount - deleteAmount);
74
162
testMaxProperty (tree);
75
- testRedBlackPropertyViolation (tree);
76
163
testTreeHeightHealth (tree);
77
164
}
0 commit comments