diff --git a/base/base.pro b/base/base.pro index 9ee7a1a728..14becbf3a3 100644 --- a/base/base.pro +++ b/base/base.pro @@ -42,7 +42,6 @@ HEADERS += \ const_helper.hpp \ exception.hpp \ internal/message.hpp \ - interval_set.hpp \ limited_priority_queue.hpp \ logging.hpp \ macros.hpp \ diff --git a/base/base_tests/base_tests.pro b/base/base_tests/base_tests.pro index 697c362deb..3635c684d4 100644 --- a/base/base_tests/base_tests.pro +++ b/base/base_tests/base_tests.pro @@ -19,7 +19,6 @@ SOURCES += \ condition_test.cpp \ const_helper.cpp \ containers_test.cpp \ - interval_set_test.cpp \ logging_test.cpp \ math_test.cpp \ matrix_test.cpp \ diff --git a/base/interval_set.hpp b/search/interval_set.hpp similarity index 80% rename from base/interval_set.hpp rename to search/interval_set.hpp index f16bf56bd7..a6db719bbb 100644 --- a/base/interval_set.hpp +++ b/search/interval_set.hpp @@ -7,14 +7,17 @@ namespace my { -// This class represents a set of disjoint half-opened intervals. +// This class represents a set of disjoint intervals in the form +// [begin, end). Note that neighbour intervals are always coalesced, +// so while [0, 1), [1, 2) and [2, 3) are disjoint, after addition to +// the set they will be stored as a single [0, 3). template class IntervalSet { public: using TInterval = pair; - // Adds an |interval| to the set. + // Adds an |interval| to the set, coalescing adjacent intervals if needed. // // Complexity: O(num of intervals intersecting with |interval| + // log(total number of intervals)). @@ -27,7 +30,7 @@ public: // log(total number of intervals)). void SubtractFrom(TInterval const & interval, vector & difference) const; - // Returns all elements of a set as a set of intervals. + // Returns all elements of the set as a set of intervals. // // Complexity: O(1). inline set const & Elems() const { return m_intervals; } @@ -56,7 +59,7 @@ void IntervalSet::Add(TInterval const & interval) TElem from = interval.first; TElem to = interval.second; - // Update |from| and |to| in accordance with corner intervals (if any). + // Updates |from| and |to| in accordance with corner intervals (if any). if (begin != end) { if (begin->first < from) @@ -69,9 +72,9 @@ void IntervalSet::Add(TInterval const & interval) } // Now all elements [from, to) can be added to the set as a single - // interval which replace all intervals in [begin, end). But note - // that it can be possible to merge new interval with its neighbors, - // so we need to check it. + // interval which will replace all intervals in [begin, end). But + // note that it can be possible to merge new interval with its + // neighbors, so following code checks it. if (begin != m_intervals.begin()) { auto prevBegin = begin; @@ -108,12 +111,12 @@ void IntervalSet::SubtractFrom(TInterval const & interval, { if (it->first > from) { - difference.emplace_back(from, min(it->first, to)); + difference.emplace_back(from, it->first); from = it->second; } else { - from = std::max(from, it->second); + from = max(from, it->second); } } diff --git a/search/retrieval.cpp b/search/retrieval.cpp index 278e8f881a..22da2d6a8b 100644 --- a/search/retrieval.cpp +++ b/search/retrieval.cpp @@ -1,6 +1,7 @@ #include "search/retrieval.hpp" #include "search/feature_offset_match.hpp" +#include "search/interval_set.hpp" #include "indexer/feature.hpp" #include "indexer/feature_algo.hpp" @@ -10,7 +11,6 @@ #include "coding/reader_wrapper.hpp" #include "base/assert.hpp" -#include "base/interval_set.hpp" #include "std/algorithm.hpp" #include "std/cmath.hpp" @@ -222,7 +222,7 @@ public: coverage = covering::SortAndMergeIntervals(coverage); coverage.erase( remove_if(coverage.begin(), coverage.end(), [this](covering::IntervalT const & interval) - { + { return m_visited.Elems().count(interval) != 0; }), coverage.end()); diff --git a/search/search.pro b/search/search.pro index 6b8ee9b95e..9469eb0b99 100644 --- a/search/search.pro +++ b/search/search.pro @@ -16,6 +16,7 @@ HEADERS += \ house_detector.hpp \ indexed_value.hpp \ intermediate_result.hpp \ + interval_set.hpp \ keyword_lang_matcher.hpp \ keyword_matcher.hpp \ latlon_match.hpp \ diff --git a/base/base_tests/interval_set_test.cpp b/search/search_tests/interval_set_test.cpp similarity index 88% rename from base/base_tests/interval_set_test.cpp rename to search/search_tests/interval_set_test.cpp index 6e4a4f2ab1..b22f73c1ce 100644 --- a/base/base_tests/interval_set_test.cpp +++ b/search/search_tests/interval_set_test.cpp @@ -1,6 +1,6 @@ #include "testing/testing.hpp" -#include "base/interval_set.hpp" +#include "search/interval_set.hpp" #include "std/initializer_list.hpp" @@ -49,6 +49,21 @@ UNIT_TEST(IntervalSet_Add) CheckSet(set, {TInterval(-4, 10)}); } +UNIT_TEST(IntervalSet_AdjacentIntervalAdd) +{ + IntervalSet set; + TEST(set.Elems().empty(), ()); + + set.Add(TInterval(100, 106)); + CheckSet(set, {TInterval(100, 106)}); + + set.Add(TInterval(106, 110)); + CheckSet(set, {TInterval(100, 110)}); + + set.Add(TInterval(90, 100)); + CheckSet(set, {TInterval(90, 110)}); +} + UNIT_TEST(IntervalSet_SubtractFrom) { IntervalSet set; @@ -89,13 +104,6 @@ UNIT_TEST(IntervalSet_SubtractFrom) TEST_EQUAL(difference, expected, ()); } - { - vector> difference; - set.SubtractFrom(TInterval(1, 5), difference); - vector> expected{TInterval(2, 4)}; - TEST_EQUAL(difference, expected, ()); - } - { vector> difference; set.SubtractFrom(TInterval(5, 7), difference); diff --git a/search/search_tests/search_tests.pro b/search/search_tests/search_tests.pro index 6e3d046df2..4849ad90ab 100644 --- a/search/search_tests/search_tests.pro +++ b/search/search_tests/search_tests.pro @@ -18,6 +18,7 @@ SOURCES += \ ../../testing/testingmain.cpp \ algos_tests.cpp \ house_detector_tests.cpp \ + interval_set_test.cpp \ keyword_lang_matcher_test.cpp \ keyword_matcher_test.cpp \ latlon_match_test.cpp \