33#include < ctime>
44#include < random>
55#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+ }
669
770class EraseTests
871 : public ::testing::Test
972{
1073public:
11- using types = IntervalTypes <int >;
74+ using interval_type = OracleInterval <int >;
1275
1376protected:
14- IntervalTypes <int >::tree_type tree;
77+ Oracle oracle;
78+ lib_interval_tree::interval_tree <OracleInterval<int >> tree;
1579 std::default_random_engine gen;
1680 std::uniform_int_distribution <int > distSmall{-500 , 500 };
1781 std::uniform_int_distribution <int > distLarge{-50000 , 50000 };
1882};
1983
2084TEST_F (EraseTests, EraseSingleElement)
2185{
22- auto inserted_interval = types:: interval_type{0 , 16 };
86+ auto inserted_interval = interval_type{&oracle, 0 , 16 };
2387
24- tree.insert (inserted_interval);
88+ tree.insert (std::move ( inserted_interval) );
2589
90+ EXPECT_EQ (oracle.livingInstances , 1 );
2691 tree.erase (tree.begin ());
2792
93+ EXPECT_EQ (oracle.livingInstances , 0 );
2894 EXPECT_EQ (tree.empty (), true );
2995 EXPECT_EQ (tree.size (), 0 );
3096}
@@ -34,11 +100,12 @@ TEST_F(EraseTests, ManualClearTest)
34100 constexpr int amount = 10'000 ;
35101
36102 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)));
38104
39105 for (auto i = std::begin (tree); i != std::end (tree);)
40106 i = tree.erase (i);
41107
108+ EXPECT_EQ (oracle.livingInstances , 0 );
42109 EXPECT_EQ (tree.empty (), true );
43110}
44111
@@ -47,20 +114,39 @@ TEST_F(EraseTests, ClearTest)
47114 constexpr int amount = 10'000 ;
48115
49116 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)));
51118
52119 tree.clear ();
53120
121+ EXPECT_EQ (oracle.livingInstances , 0 );
54122 EXPECT_EQ (tree.empty (), true );
55123}
56124
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+
57143TEST_F (EraseTests, RandomEraseTest)
58144{
59145 constexpr int amount = 10'000 ;
60- constexpr int deleteAmount = 20 ;
146+ constexpr int deleteAmount = 50 ;
61147
62148 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)));
64150
65151 for (int i = 0 ; i != deleteAmount; ++i)
66152 {
@@ -69,9 +155,10 @@ TEST_F(EraseTests, RandomEraseTest)
69155 auto iter = tree.begin ();
70156 for (int j = 0 ; j != end; ++j)
71157 ++iter;
158+ tree.erase (iter);
72159 }
73160
161+ EXPECT_EQ (oracle.livingInstances , amount - deleteAmount);
74162 testMaxProperty (tree);
75- testRedBlackPropertyViolation (tree);
76163 testTreeHeightHealth (tree);
77164}
0 commit comments