From 5e03dea65d3e53add95c9794193c19c67a2d3ef9 Mon Sep 17 00:00:00 2001 From: Tomasz Grabiec Date: Fri, 24 Jul 2015 12:02:51 +0200 Subject: [PATCH] range: Fix is_wrap_around() In Origin, dht.Range() with equal values is considered a full wrap around. Make our range<> recognize this. So we have: ]x; x] - wrap around, full ring [x; x[ - wrap around, full ring ]x; x[ - wrap around, excluding x [x; x] - not wrap around, only x included --- query-request.hh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/query-request.hh b/query-request.hh index 60cf20ae0b..1a369b15aa 100644 --- a/query-request.hh +++ b/query-request.hh @@ -108,14 +108,17 @@ public: const optional& end() const { return _singular ? _start : _end; } - // end is smaller than start + // Range is a wrap around if end value is smaller than the start value + // or they're equal and at least one bound is not inclusive. // Comparator must define a total ordering on T. template bool is_wrap_around(Comparator&& cmp) const { if (_end && _start) { - return cmp(end()->value(), start()->value()) < 0; + auto r = cmp(end()->value(), start()->value()); + return r < 0 + || (r == 0 && (!start()->is_inclusive() || !end()->is_inclusive())); } else { - return false; // open ended range never wraps around + return false; // open ended range or singular range don't wrap around } } // Converts a wrap-around range to two non-wrap-around ranges. @@ -131,8 +134,9 @@ public: template bool contains(const T& point, Comparator&& cmp) const { if (is_wrap_around(cmp)) { - // wrapped range contains point if reverse does not contain it - return !range::make({end()->value(), !_end->is_inclusive()}, {start()->value(), !_start->is_inclusive()}).contains(point, cmp); + auto unwrapped = unwrap(); + return unwrapped.first.contains(point, cmp) + || unwrapped.second.contains(point, cmp); } else { return !before(point, cmp) && !after(point, cmp); }