range: Find a sequence's lower and upper bounds

This patch extracts a pair of functions from mutation_partition to
calculate the lower and upper bounds of a sequence from a
nonwrapping_range.

Signed-off-by: Duarte Nunes <duarte@scylladb.com>
This commit is contained in:
Duarte Nunes
2016-11-17 21:30:14 +00:00
parent 636287fdf2
commit bdba8d99c3
2 changed files with 53 additions and 6 deletions

View File

@@ -512,17 +512,13 @@ mutation_partition::clustered_row(const schema& s, const clustering_key_view& ke
mutation_partition::rows_type::const_iterator
mutation_partition::lower_bound(const schema& schema, const query::clustering_range& r) const {
auto cmp = rows_entry::key_comparator(clustering_key_prefix::prefix_equality_less_compare(schema));
return r.start() ? (r.start()->is_inclusive()
? _rows.lower_bound(r.start()->value(), cmp)
: _rows.upper_bound(r.start()->value(), cmp)) : _rows.cbegin();
return r.lower_bound(_rows, std::move(cmp));
}
mutation_partition::rows_type::const_iterator
mutation_partition::upper_bound(const schema& schema, const query::clustering_range& r) const {
auto cmp = rows_entry::key_comparator(clustering_key_prefix::prefix_equality_less_compare(schema));
return r.end() ? (r.end()->is_inclusive()
? _rows.upper_bound(r.end()->value(), cmp)
: _rows.lower_bound(r.end()->value(), cmp)) : _rows.cend();
return r.upper_bound(_rows, std::move(cmp));
}
boost::iterator_range<mutation_partition::rows_type::const_iterator>

View File

@@ -592,6 +592,57 @@ public:
deoverlapped_ranges.emplace_back(std::move(current));
return deoverlapped_ranges;
}
private:
// These private functions optimize the case where a sequence supports the
// lower and upper bound operations more efficiently, as is the case with
// some boost containers.
struct std_ {};
struct built_in_ : std_ {};
template<typename Range, typename LessComparator,
typename = decltype(&std::remove_reference<Range>::type::lower_bound)>
typename std::remove_reference<Range>::type::const_iterator do_lower_bound(const T& value, Range&& r, LessComparator&& cmp, built_in_) const {
return r.lower_bound(value, std::forward<LessComparator>(cmp));
}
template<typename Range, typename LessComparator,
typename = decltype(&std::remove_reference<Range>::type::upper_bound)>
typename std::remove_reference<Range>::type::const_iterator do_upper_bound(const T& value, Range&& r, LessComparator&& cmp, built_in_) const {
return r.upper_bound(value, std::forward<LessComparator>(cmp));
}
template<typename Range, typename LessComparator>
typename std::remove_reference<Range>::type::const_iterator do_lower_bound(const T& value, Range&& r, LessComparator&& cmp, std_) const {
return std::lower_bound(r.begin(), r.end(), value, std::forward<LessComparator>(cmp));
}
template<typename Range, typename LessComparator>
typename std::remove_reference<Range>::type::const_iterator do_upper_bound(const T& value, Range&& r, LessComparator&& cmp, std_) const {
return std::upper_bound(r.begin(), r.end(), value, std::forward<LessComparator>(cmp));
}
public:
// Return the lower bound of the specified sequence according to these bounds.
template<typename Range, typename LessComparator>
typename std::remove_reference<Range>::type::const_iterator lower_bound(Range&& r, LessComparator&& cmp) const {
return start()
? (start()->is_inclusive()
? do_lower_bound(start()->value(), std::forward<Range>(r), std::forward<LessComparator>(cmp), built_in_())
: do_upper_bound(start()->value(), std::forward<Range>(r), std::forward<LessComparator>(cmp), built_in_()))
: std::cbegin(r);
}
// Return the upper bound of the specified sequence according to these bounds.
template<typename Range, typename LessComparator>
typename std::remove_reference<Range>::type::const_iterator upper_bound(Range&& r, LessComparator&& cmp) const {
return end()
? (end()->is_inclusive()
? do_upper_bound(end()->value(), std::forward<Range>(r), std::forward<LessComparator>(cmp), built_in_())
: do_lower_bound(end()->value(), std::forward<Range>(r), std::forward<LessComparator>(cmp), built_in_()))
: (is_singular()
? do_upper_bound(start()->value(), std::forward<Range>(r), std::forward<LessComparator>(cmp), built_in_())
: std::cend(r));
}
template<typename U>
friend std::ostream& operator<<(std::ostream& out, const nonwrapping_range<U>& r);
};