aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/containers/disjoint_interval_tree
diff options
context:
space:
mode:
authorVasily Gerasimov <UgnineSirdis@gmail.com>2022-02-10 16:49:10 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:49:10 +0300
commit1eb755fbca92172a6aec2f57371b2b3a19dfab43 (patch)
tree5d5cb817648f650d76cf1076100726fd9b8448e8 /library/cpp/containers/disjoint_interval_tree
parent6cdc8f140213c595e4ad38bc3d97fcef1146b8c3 (diff)
downloadydb-1eb755fbca92172a6aec2f57371b2b3a19dfab43.tar.gz
Restoring authorship annotation for Vasily Gerasimov <UgnineSirdis@gmail.com>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/containers/disjoint_interval_tree')
-rw-r--r--library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.cpp2
-rw-r--r--library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.h526
-rw-r--r--library/cpp/containers/disjoint_interval_tree/ut/disjoint_interval_tree_ut.cpp526
-rw-r--r--library/cpp/containers/disjoint_interval_tree/ut/ya.make24
-rw-r--r--library/cpp/containers/disjoint_interval_tree/ya.make20
5 files changed, 549 insertions, 549 deletions
diff --git a/library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.cpp b/library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.cpp
index ff3b6c2ff6..7334a43c36 100644
--- a/library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.cpp
+++ b/library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.cpp
@@ -1 +1 @@
-#include "disjoint_interval_tree.h"
+#include "disjoint_interval_tree.h"
diff --git a/library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.h b/library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.h
index d3bd6f7748..1f899c9991 100644
--- a/library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.h
+++ b/library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.h
@@ -1,227 +1,227 @@
-#pragma once
-
-#include <util/generic/map.h>
-#include <util/system/yassert.h>
-
-#include <type_traits>
-
-template <class T>
-class TDisjointIntervalTree {
-private:
- static_assert(std::is_integral<T>::value, "expect std::is_integral<T>::value");
-
- using TTree = TMap<T, T>; // [key, value)
- using TIterator = typename TTree::iterator;
- using TConstIterator = typename TTree::const_iterator;
- using TReverseIterator = typename TTree::reverse_iterator;
- using TThis = TDisjointIntervalTree<T>;
-
- TTree Tree;
- size_t NumElements;
-
-public:
- TDisjointIntervalTree()
- : NumElements()
- {
- }
-
- void Insert(const T t) {
- InsertInterval(t, t + 1);
- }
-
- // we assume that none of elements from [begin, end) belong to tree.
- void InsertInterval(const T begin, const T end) {
- InsertIntervalImpl(begin, end);
- NumElements += (size_t)(end - begin);
- }
-
- bool Has(const T t) const {
- return const_cast<TThis*>(this)->FindContaining(t) != Tree.end();
- }
-
- bool Intersects(const T begin, const T end) {
- if (Empty()) {
- return false;
- }
-
- TIterator l = Tree.lower_bound(begin);
- if (l != Tree.end()) {
- if (l->first < end) {
- return true;
- } else if (l != Tree.begin()) {
- --l;
- return l->second > begin;
- } else {
- return false;
- }
- } else {
- auto last = Tree.rbegin();
- return begin < last->second;
- }
- }
-
- TConstIterator FindContaining(const T t) const {
- return const_cast<TThis*>(this)->FindContaining(t);
- }
-
- // Erase element. Returns true when element has been deleted, otherwise false.
- bool Erase(const T t) {
- TIterator n = FindContaining(t);
- if (n == Tree.end()) {
- return false;
- }
-
- --NumElements;
-
- T& begin = const_cast<T&>(n->first);
- T& end = const_cast<T&>(n->second);
-
- // Optimization hack.
- if (t == begin) {
- if (++begin == end) { // OK to change key since intervals do not intersect.
- Tree.erase(n);
- return true;
- }
-
- } else if (t == end - 1) {
- --end;
-
- } else {
- const T e = end;
- end = t;
- InsertIntervalImpl(t + 1, e);
- }
-
- Y_ASSERT(begin < end);
- return true;
- }
-
- // Erase interval. Returns number of elements removed from set.
- size_t EraseInterval(const T begin, const T end) {
- Y_ASSERT(begin < end);
-
- if (Empty()) {
- return 0;
- }
-
- size_t elementsRemoved = 0;
-
- TIterator completelyRemoveBegin = Tree.lower_bound(begin);
- if ((completelyRemoveBegin != Tree.end() && completelyRemoveBegin->first > begin && completelyRemoveBegin != Tree.begin())
- || completelyRemoveBegin == Tree.end()) {
- // Look at the interval. It could contain [begin, end).
- TIterator containingBegin = completelyRemoveBegin;
- --containingBegin;
- if (containingBegin->first < begin && begin < containingBegin->second) { // Contains begin.
- if (containingBegin->second > end) { // Contains end.
- const T prevEnd = containingBegin->second;
- Y_ASSERT(containingBegin->second - begin <= NumElements);
-
- Y_ASSERT(containingBegin->second - containingBegin->first > end - begin);
- containingBegin->second = begin;
- InsertIntervalImpl(end, prevEnd);
-
- elementsRemoved = end - begin;
- NumElements -= elementsRemoved;
- return elementsRemoved;
- } else {
- elementsRemoved += containingBegin->second - begin;
- containingBegin->second = begin;
- }
- }
- }
-
- TIterator completelyRemoveEnd = completelyRemoveBegin != Tree.end() ? Tree.lower_bound(end) : Tree.end();
- if (completelyRemoveEnd != Tree.end() && completelyRemoveEnd != Tree.begin() && completelyRemoveEnd->first != end) {
- TIterator containingEnd = completelyRemoveEnd;
- --containingEnd;
- if (containingEnd->second > end) {
- T& leftBorder = const_cast<T&>(containingEnd->first);
-
- Y_ASSERT(leftBorder < end);
-
- --completelyRemoveEnd; // Don't remove the whole interval.
-
- // Optimization hack.
- elementsRemoved += end - leftBorder;
- leftBorder = end; // OK to change key since intervals do not intersect.
- }
- }
-
- for (TIterator i = completelyRemoveBegin; i != completelyRemoveEnd; ++i) {
- elementsRemoved += i->second - i->first;
- }
-
- Tree.erase(completelyRemoveBegin, completelyRemoveEnd);
-
- Y_ASSERT(elementsRemoved <= NumElements);
- NumElements -= elementsRemoved;
-
- return elementsRemoved;
- }
-
- void Swap(TDisjointIntervalTree& rhv) {
- Tree.swap(rhv.Tree);
- std::swap(NumElements, rhv.NumElements);
- }
-
- void Clear() {
- Tree.clear();
- NumElements = 0;
- }
-
- bool Empty() const {
- return Tree.empty();
- }
-
- size_t GetNumElements() const {
- return NumElements;
- }
-
- size_t GetNumIntervals() const {
- return Tree.size();
- }
-
- T Min() const {
- Y_ASSERT(!Empty());
- return Tree.begin()->first;
- }
-
- T Max() const {
- Y_ASSERT(!Empty());
- return Tree.rbegin()->second;
- }
-
- TConstIterator begin() const {
- return Tree.begin();
- }
-
- TConstIterator end() const {
- return Tree.end();
- }
-
-private:
- void InsertIntervalImpl(const T begin, const T end) {
- Y_ASSERT(begin < end);
- Y_ASSERT(!Intersects(begin, end));
-
- TIterator l = Tree.lower_bound(begin);
- TIterator p = Tree.end();
- if (l != Tree.begin()) {
- p = l;
- --p;
- }
-
-#ifndef NDEBUG
- TIterator u = Tree.upper_bound(begin);
- Y_VERIFY_DEBUG(u == Tree.end() || u->first >= end, "Trying to add [%" PRIu64 ", %" PRIu64 ") which intersects with existing [%" PRIu64 ", %" PRIu64 ")", begin, end, u->first, u->second);
- Y_VERIFY_DEBUG(l == Tree.end() || l == u, "Trying to add [%" PRIu64 ", %" PRIu64 ") which intersects with existing [%" PRIu64 ", %" PRIu64 ")", begin, end, l->first, l->second);
- Y_VERIFY_DEBUG(p == Tree.end() || p->second <= begin, "Trying to add [%" PRIu64 ", %" PRIu64 ") which intersects with existing [%" PRIu64 ", %" PRIu64 ")", begin, end, p->first, p->second);
-#endif
-
- // try to extend interval
- if (p != Tree.end() && p->second == begin) {
- p->second = end;
+#pragma once
+
+#include <util/generic/map.h>
+#include <util/system/yassert.h>
+
+#include <type_traits>
+
+template <class T>
+class TDisjointIntervalTree {
+private:
+ static_assert(std::is_integral<T>::value, "expect std::is_integral<T>::value");
+
+ using TTree = TMap<T, T>; // [key, value)
+ using TIterator = typename TTree::iterator;
+ using TConstIterator = typename TTree::const_iterator;
+ using TReverseIterator = typename TTree::reverse_iterator;
+ using TThis = TDisjointIntervalTree<T>;
+
+ TTree Tree;
+ size_t NumElements;
+
+public:
+ TDisjointIntervalTree()
+ : NumElements()
+ {
+ }
+
+ void Insert(const T t) {
+ InsertInterval(t, t + 1);
+ }
+
+ // we assume that none of elements from [begin, end) belong to tree.
+ void InsertInterval(const T begin, const T end) {
+ InsertIntervalImpl(begin, end);
+ NumElements += (size_t)(end - begin);
+ }
+
+ bool Has(const T t) const {
+ return const_cast<TThis*>(this)->FindContaining(t) != Tree.end();
+ }
+
+ bool Intersects(const T begin, const T end) {
+ if (Empty()) {
+ return false;
+ }
+
+ TIterator l = Tree.lower_bound(begin);
+ if (l != Tree.end()) {
+ if (l->first < end) {
+ return true;
+ } else if (l != Tree.begin()) {
+ --l;
+ return l->second > begin;
+ } else {
+ return false;
+ }
+ } else {
+ auto last = Tree.rbegin();
+ return begin < last->second;
+ }
+ }
+
+ TConstIterator FindContaining(const T t) const {
+ return const_cast<TThis*>(this)->FindContaining(t);
+ }
+
+ // Erase element. Returns true when element has been deleted, otherwise false.
+ bool Erase(const T t) {
+ TIterator n = FindContaining(t);
+ if (n == Tree.end()) {
+ return false;
+ }
+
+ --NumElements;
+
+ T& begin = const_cast<T&>(n->first);
+ T& end = const_cast<T&>(n->second);
+
+ // Optimization hack.
+ if (t == begin) {
+ if (++begin == end) { // OK to change key since intervals do not intersect.
+ Tree.erase(n);
+ return true;
+ }
+
+ } else if (t == end - 1) {
+ --end;
+
+ } else {
+ const T e = end;
+ end = t;
+ InsertIntervalImpl(t + 1, e);
+ }
+
+ Y_ASSERT(begin < end);
+ return true;
+ }
+
+ // Erase interval. Returns number of elements removed from set.
+ size_t EraseInterval(const T begin, const T end) {
+ Y_ASSERT(begin < end);
+
+ if (Empty()) {
+ return 0;
+ }
+
+ size_t elementsRemoved = 0;
+
+ TIterator completelyRemoveBegin = Tree.lower_bound(begin);
+ if ((completelyRemoveBegin != Tree.end() && completelyRemoveBegin->first > begin && completelyRemoveBegin != Tree.begin())
+ || completelyRemoveBegin == Tree.end()) {
+ // Look at the interval. It could contain [begin, end).
+ TIterator containingBegin = completelyRemoveBegin;
+ --containingBegin;
+ if (containingBegin->first < begin && begin < containingBegin->second) { // Contains begin.
+ if (containingBegin->second > end) { // Contains end.
+ const T prevEnd = containingBegin->second;
+ Y_ASSERT(containingBegin->second - begin <= NumElements);
+
+ Y_ASSERT(containingBegin->second - containingBegin->first > end - begin);
+ containingBegin->second = begin;
+ InsertIntervalImpl(end, prevEnd);
+
+ elementsRemoved = end - begin;
+ NumElements -= elementsRemoved;
+ return elementsRemoved;
+ } else {
+ elementsRemoved += containingBegin->second - begin;
+ containingBegin->second = begin;
+ }
+ }
+ }
+
+ TIterator completelyRemoveEnd = completelyRemoveBegin != Tree.end() ? Tree.lower_bound(end) : Tree.end();
+ if (completelyRemoveEnd != Tree.end() && completelyRemoveEnd != Tree.begin() && completelyRemoveEnd->first != end) {
+ TIterator containingEnd = completelyRemoveEnd;
+ --containingEnd;
+ if (containingEnd->second > end) {
+ T& leftBorder = const_cast<T&>(containingEnd->first);
+
+ Y_ASSERT(leftBorder < end);
+
+ --completelyRemoveEnd; // Don't remove the whole interval.
+
+ // Optimization hack.
+ elementsRemoved += end - leftBorder;
+ leftBorder = end; // OK to change key since intervals do not intersect.
+ }
+ }
+
+ for (TIterator i = completelyRemoveBegin; i != completelyRemoveEnd; ++i) {
+ elementsRemoved += i->second - i->first;
+ }
+
+ Tree.erase(completelyRemoveBegin, completelyRemoveEnd);
+
+ Y_ASSERT(elementsRemoved <= NumElements);
+ NumElements -= elementsRemoved;
+
+ return elementsRemoved;
+ }
+
+ void Swap(TDisjointIntervalTree& rhv) {
+ Tree.swap(rhv.Tree);
+ std::swap(NumElements, rhv.NumElements);
+ }
+
+ void Clear() {
+ Tree.clear();
+ NumElements = 0;
+ }
+
+ bool Empty() const {
+ return Tree.empty();
+ }
+
+ size_t GetNumElements() const {
+ return NumElements;
+ }
+
+ size_t GetNumIntervals() const {
+ return Tree.size();
+ }
+
+ T Min() const {
+ Y_ASSERT(!Empty());
+ return Tree.begin()->first;
+ }
+
+ T Max() const {
+ Y_ASSERT(!Empty());
+ return Tree.rbegin()->second;
+ }
+
+ TConstIterator begin() const {
+ return Tree.begin();
+ }
+
+ TConstIterator end() const {
+ return Tree.end();
+ }
+
+private:
+ void InsertIntervalImpl(const T begin, const T end) {
+ Y_ASSERT(begin < end);
+ Y_ASSERT(!Intersects(begin, end));
+
+ TIterator l = Tree.lower_bound(begin);
+ TIterator p = Tree.end();
+ if (l != Tree.begin()) {
+ p = l;
+ --p;
+ }
+
+#ifndef NDEBUG
+ TIterator u = Tree.upper_bound(begin);
+ Y_VERIFY_DEBUG(u == Tree.end() || u->first >= end, "Trying to add [%" PRIu64 ", %" PRIu64 ") which intersects with existing [%" PRIu64 ", %" PRIu64 ")", begin, end, u->first, u->second);
+ Y_VERIFY_DEBUG(l == Tree.end() || l == u, "Trying to add [%" PRIu64 ", %" PRIu64 ") which intersects with existing [%" PRIu64 ", %" PRIu64 ")", begin, end, l->first, l->second);
+ Y_VERIFY_DEBUG(p == Tree.end() || p->second <= begin, "Trying to add [%" PRIu64 ", %" PRIu64 ") which intersects with existing [%" PRIu64 ", %" PRIu64 ")", begin, end, p->first, p->second);
+#endif
+
+ // try to extend interval
+ if (p != Tree.end() && p->second == begin) {
+ p->second = end;
//Try to merge 2 intervals - p and next one if possible
auto next = p;
// Next is not Tree.end() here.
@@ -231,42 +231,42 @@ private:
Tree.erase(next);
}
// Maybe new interval extends right interval
- } else if (l != Tree.end() && end == l->first) {
- T& leftBorder = const_cast<T&>(l->first);
- // Optimization hack.
- leftBorder = begin; // OK to change key since intervals do not intersect.
- } else {
- Tree.insert(std::make_pair(begin, end));
- }
- }
-
- TIterator FindContaining(const T t) {
- TIterator l = Tree.lower_bound(t);
- if (l != Tree.end()) {
- if (l->first == t) {
- return l;
- }
- Y_ASSERT(l->first > t);
-
- if (l == Tree.begin()) {
- return Tree.end();
- }
-
- --l;
- Y_ASSERT(l->first != t);
-
- if (l->first < t && t < l->second) {
- return l;
- }
-
- } else if (!Tree.empty()) { // l is larger than Begin of any interval, but maybe it belongs to last interval?
- TReverseIterator last = Tree.rbegin();
- Y_ASSERT(last->first != t);
-
- if (last->first < t && t < last->second) {
- return (++last).base();
- }
- }
- return Tree.end();
- }
-};
+ } else if (l != Tree.end() && end == l->first) {
+ T& leftBorder = const_cast<T&>(l->first);
+ // Optimization hack.
+ leftBorder = begin; // OK to change key since intervals do not intersect.
+ } else {
+ Tree.insert(std::make_pair(begin, end));
+ }
+ }
+
+ TIterator FindContaining(const T t) {
+ TIterator l = Tree.lower_bound(t);
+ if (l != Tree.end()) {
+ if (l->first == t) {
+ return l;
+ }
+ Y_ASSERT(l->first > t);
+
+ if (l == Tree.begin()) {
+ return Tree.end();
+ }
+
+ --l;
+ Y_ASSERT(l->first != t);
+
+ if (l->first < t && t < l->second) {
+ return l;
+ }
+
+ } else if (!Tree.empty()) { // l is larger than Begin of any interval, but maybe it belongs to last interval?
+ TReverseIterator last = Tree.rbegin();
+ Y_ASSERT(last->first != t);
+
+ if (last->first < t && t < last->second) {
+ return (++last).base();
+ }
+ }
+ return Tree.end();
+ }
+};
diff --git a/library/cpp/containers/disjoint_interval_tree/ut/disjoint_interval_tree_ut.cpp b/library/cpp/containers/disjoint_interval_tree/ut/disjoint_interval_tree_ut.cpp
index 0292c72282..8474ae89b0 100644
--- a/library/cpp/containers/disjoint_interval_tree/ut/disjoint_interval_tree_ut.cpp
+++ b/library/cpp/containers/disjoint_interval_tree/ut/disjoint_interval_tree_ut.cpp
@@ -1,60 +1,60 @@
-#include <library/cpp/testing/unittest/registar.h>
-
-#include <library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.h>
-
-Y_UNIT_TEST_SUITE(DisjointIntervalTreeTest) {
- Y_UNIT_TEST(GenericTest) {
- TDisjointIntervalTree<ui64> tree;
- tree.Insert(1);
- tree.Insert(50);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 2);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 2);
-
- tree.InsertInterval(10, 30);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 22);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.Min(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.Max(), 51);
-
- tree.Erase(20);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 4);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 21);
-
- tree.Clear();
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 0);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 0);
- }
-
- Y_UNIT_TEST(MergeIntervalsTest) {
- TDisjointIntervalTree<ui64> tree;
- tree.Insert(5);
-
- // Insert interval from right side.
- tree.Insert(6);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 2);
-
- {
- auto begin = tree.begin();
- UNIT_ASSERT_VALUES_EQUAL(begin->first, 5);
- UNIT_ASSERT_VALUES_EQUAL(begin->second, 7);
-
- ++begin;
- UNIT_ASSERT_EQUAL(begin, tree.end());
- }
-
- // Insert interval from left side.
- tree.InsertInterval(2, 5);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
-
- {
- auto begin = tree.begin();
- UNIT_ASSERT_VALUES_EQUAL(begin->first, 2);
- UNIT_ASSERT_VALUES_EQUAL(begin->second, 7);
- }
+#include <library/cpp/testing/unittest/registar.h>
+
+#include <library/cpp/containers/disjoint_interval_tree/disjoint_interval_tree.h>
+
+Y_UNIT_TEST_SUITE(DisjointIntervalTreeTest) {
+ Y_UNIT_TEST(GenericTest) {
+ TDisjointIntervalTree<ui64> tree;
+ tree.Insert(1);
+ tree.Insert(50);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 2);
+
+ tree.InsertInterval(10, 30);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 22);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.Min(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.Max(), 51);
+
+ tree.Erase(20);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 21);
+
+ tree.Clear();
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 0);
+ }
+
+ Y_UNIT_TEST(MergeIntervalsTest) {
+ TDisjointIntervalTree<ui64> tree;
+ tree.Insert(5);
+
+ // Insert interval from right side.
+ tree.Insert(6);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 2);
+
+ {
+ auto begin = tree.begin();
+ UNIT_ASSERT_VALUES_EQUAL(begin->first, 5);
+ UNIT_ASSERT_VALUES_EQUAL(begin->second, 7);
+
+ ++begin;
+ UNIT_ASSERT_EQUAL(begin, tree.end());
+ }
+
+ // Insert interval from left side.
+ tree.InsertInterval(2, 5);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
+
+ {
+ auto begin = tree.begin();
+ UNIT_ASSERT_VALUES_EQUAL(begin->first, 2);
+ UNIT_ASSERT_VALUES_EQUAL(begin->second, 7);
+ }
// Merge all intervals.
{
@@ -71,209 +71,209 @@ Y_UNIT_TEST_SUITE(DisjointIntervalTreeTest) {
UNIT_ASSERT_VALUES_EQUAL(begin->second, 10);
}
- }
-
- Y_UNIT_TEST(EraseIntervalTest) {
- // 1. Remove from empty tree.
- {
- TDisjointIntervalTree<ui64> tree;
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(1, 3), 0);
- }
-
- // 2. No such interval in set.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(1, 3), 0);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(20, 30), 0);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
- }
-
- // 3. Remove the whole tree.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(0, 100), 5);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 0);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 0);
- UNIT_ASSERT(tree.Empty());
- }
-
- // 4. Remove the whole tree with borders specified exactly as in tree.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(5, 10), 5);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 0);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 0);
- UNIT_ASSERT(tree.Empty());
- }
-
- // 5. Specify left border exactly as in existing interval.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- tree.InsertInterval(15, 20);
- tree.InsertInterval(25, 30);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(15, 100500), 10);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
- }
-
- // 6. Specify left border somewhere in existing interval.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- tree.InsertInterval(15, 20);
- tree.InsertInterval(25, 30);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(16, 100500), 9);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 2);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 6);
- }
-
- // 7. Remove from the center of existing interval.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- tree.InsertInterval(15, 20);
- tree.InsertInterval(25, 30);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(17, 19), 2);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 4);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 13);
-
- UNIT_ASSERT(tree.Has(16));
- UNIT_ASSERT(tree.Has(19));
- }
-
- // 8. Remove from the center of the only existing interval.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(15, 20);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(17, 19), 2);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 2);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 3);
-
- UNIT_ASSERT(tree.Has(16));
- UNIT_ASSERT(tree.Has(19));
- }
-
- // 9. Specify borders between existing intervals.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- tree.InsertInterval(15, 20);
- tree.InsertInterval(25, 30);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(10, 15), 0);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(13, 15), 0);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(10, 13), 0);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
- }
-
- // 10. Specify right border exactly as in existing interval.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- tree.InsertInterval(15, 20);
- tree.InsertInterval(25, 30);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(0, 20), 10);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
- }
-
- // 11. Specify right border somewhere in existing interval.
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- tree.InsertInterval(15, 20);
- tree.InsertInterval(25, 30);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
-
- UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(2, 17), 7);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 2);
- UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 8);
- }
- }
-
- Y_UNIT_TEST(IntersectsTest) {
- {
- TDisjointIntervalTree<ui64> tree;
- UNIT_ASSERT(!tree.Intersects(1, 2));
- }
-
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
-
- UNIT_ASSERT(tree.Intersects(5, 10));
- UNIT_ASSERT(tree.Intersects(5, 6));
- UNIT_ASSERT(tree.Intersects(9, 10));
- UNIT_ASSERT(tree.Intersects(6, 8));
- UNIT_ASSERT(tree.Intersects(1, 8));
- UNIT_ASSERT(tree.Intersects(8, 15));
- UNIT_ASSERT(tree.Intersects(3, 14));
-
- UNIT_ASSERT(!tree.Intersects(3, 5));
- UNIT_ASSERT(!tree.Intersects(10, 13));
- }
-
- {
- TDisjointIntervalTree<ui64> tree;
- tree.InsertInterval(5, 10);
- tree.InsertInterval(20, 30);
-
- UNIT_ASSERT(tree.Intersects(5, 10));
- UNIT_ASSERT(tree.Intersects(5, 6));
- UNIT_ASSERT(tree.Intersects(9, 10));
- UNIT_ASSERT(tree.Intersects(6, 8));
- UNIT_ASSERT(tree.Intersects(1, 8));
- UNIT_ASSERT(tree.Intersects(8, 15));
- UNIT_ASSERT(tree.Intersects(3, 14));
- UNIT_ASSERT(tree.Intersects(18, 21));
- UNIT_ASSERT(tree.Intersects(3, 50));
-
- UNIT_ASSERT(!tree.Intersects(3, 5));
- UNIT_ASSERT(!tree.Intersects(10, 13));
- UNIT_ASSERT(!tree.Intersects(15, 18));
- }
- }
-}
+ }
+
+ Y_UNIT_TEST(EraseIntervalTest) {
+ // 1. Remove from empty tree.
+ {
+ TDisjointIntervalTree<ui64> tree;
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(1, 3), 0);
+ }
+
+ // 2. No such interval in set.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(1, 3), 0);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(20, 30), 0);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
+ }
+
+ // 3. Remove the whole tree.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(0, 100), 5);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 0);
+ UNIT_ASSERT(tree.Empty());
+ }
+
+ // 4. Remove the whole tree with borders specified exactly as in tree.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(5, 10), 5);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 0);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 0);
+ UNIT_ASSERT(tree.Empty());
+ }
+
+ // 5. Specify left border exactly as in existing interval.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ tree.InsertInterval(15, 20);
+ tree.InsertInterval(25, 30);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(15, 100500), 10);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
+ }
+
+ // 6. Specify left border somewhere in existing interval.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ tree.InsertInterval(15, 20);
+ tree.InsertInterval(25, 30);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(16, 100500), 9);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 6);
+ }
+
+ // 7. Remove from the center of existing interval.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ tree.InsertInterval(15, 20);
+ tree.InsertInterval(25, 30);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(17, 19), 2);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 4);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 13);
+
+ UNIT_ASSERT(tree.Has(16));
+ UNIT_ASSERT(tree.Has(19));
+ }
+
+ // 8. Remove from the center of the only existing interval.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(15, 20);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(17, 19), 2);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 3);
+
+ UNIT_ASSERT(tree.Has(16));
+ UNIT_ASSERT(tree.Has(19));
+ }
+
+ // 9. Specify borders between existing intervals.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ tree.InsertInterval(15, 20);
+ tree.InsertInterval(25, 30);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(10, 15), 0);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(13, 15), 0);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(10, 13), 0);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
+ }
+
+ // 10. Specify right border exactly as in existing interval.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ tree.InsertInterval(15, 20);
+ tree.InsertInterval(25, 30);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(0, 20), 10);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 1);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 5);
+ }
+
+ // 11. Specify right border somewhere in existing interval.
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ tree.InsertInterval(15, 20);
+ tree.InsertInterval(25, 30);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 3);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 15);
+
+ UNIT_ASSERT_VALUES_EQUAL(tree.EraseInterval(2, 17), 7);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumIntervals(), 2);
+ UNIT_ASSERT_VALUES_EQUAL(tree.GetNumElements(), 8);
+ }
+ }
+
+ Y_UNIT_TEST(IntersectsTest) {
+ {
+ TDisjointIntervalTree<ui64> tree;
+ UNIT_ASSERT(!tree.Intersects(1, 2));
+ }
+
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+
+ UNIT_ASSERT(tree.Intersects(5, 10));
+ UNIT_ASSERT(tree.Intersects(5, 6));
+ UNIT_ASSERT(tree.Intersects(9, 10));
+ UNIT_ASSERT(tree.Intersects(6, 8));
+ UNIT_ASSERT(tree.Intersects(1, 8));
+ UNIT_ASSERT(tree.Intersects(8, 15));
+ UNIT_ASSERT(tree.Intersects(3, 14));
+
+ UNIT_ASSERT(!tree.Intersects(3, 5));
+ UNIT_ASSERT(!tree.Intersects(10, 13));
+ }
+
+ {
+ TDisjointIntervalTree<ui64> tree;
+ tree.InsertInterval(5, 10);
+ tree.InsertInterval(20, 30);
+
+ UNIT_ASSERT(tree.Intersects(5, 10));
+ UNIT_ASSERT(tree.Intersects(5, 6));
+ UNIT_ASSERT(tree.Intersects(9, 10));
+ UNIT_ASSERT(tree.Intersects(6, 8));
+ UNIT_ASSERT(tree.Intersects(1, 8));
+ UNIT_ASSERT(tree.Intersects(8, 15));
+ UNIT_ASSERT(tree.Intersects(3, 14));
+ UNIT_ASSERT(tree.Intersects(18, 21));
+ UNIT_ASSERT(tree.Intersects(3, 50));
+
+ UNIT_ASSERT(!tree.Intersects(3, 5));
+ UNIT_ASSERT(!tree.Intersects(10, 13));
+ UNIT_ASSERT(!tree.Intersects(15, 18));
+ }
+ }
+}
diff --git a/library/cpp/containers/disjoint_interval_tree/ut/ya.make b/library/cpp/containers/disjoint_interval_tree/ut/ya.make
index 0885923e71..6736ce0c2b 100644
--- a/library/cpp/containers/disjoint_interval_tree/ut/ya.make
+++ b/library/cpp/containers/disjoint_interval_tree/ut/ya.make
@@ -1,12 +1,12 @@
-UNITTEST_FOR(library/cpp/containers/disjoint_interval_tree)
-
-OWNER(
- dcherednik
- galaxycrab
-)
-
-SRCS(
- disjoint_interval_tree_ut.cpp
-)
-
-END()
+UNITTEST_FOR(library/cpp/containers/disjoint_interval_tree)
+
+OWNER(
+ dcherednik
+ galaxycrab
+)
+
+SRCS(
+ disjoint_interval_tree_ut.cpp
+)
+
+END()
diff --git a/library/cpp/containers/disjoint_interval_tree/ya.make b/library/cpp/containers/disjoint_interval_tree/ya.make
index cafad0281e..b4f5a52a67 100644
--- a/library/cpp/containers/disjoint_interval_tree/ya.make
+++ b/library/cpp/containers/disjoint_interval_tree/ya.make
@@ -1,10 +1,10 @@
-OWNER(
- dcherednik
- galaxycrab
-)
-
-LIBRARY()
-
-SRCS(disjoint_interval_tree.cpp)
-
-END()
+OWNER(
+ dcherednik
+ galaxycrab
+)
+
+LIBRARY()
+
+SRCS(disjoint_interval_tree.cpp)
+
+END()