diff options
Diffstat (limited to 'src/mongo/db/query/interval.cpp')
-rw-r--r-- | src/mongo/db/query/interval.cpp | 356 |
1 files changed, 176 insertions, 180 deletions
diff --git a/src/mongo/db/query/interval.cpp b/src/mongo/db/query/interval.cpp index cdbb7abbb6d..2f35dc2eccb 100644 --- a/src/mongo/db/query/interval.cpp +++ b/src/mongo/db/query/interval.cpp @@ -30,167 +30,164 @@ namespace mongo { - using std::string; - - Interval::Interval() - : _intervalData(BSONObj()), start(BSONElement()), startInclusive(false), end(BSONElement()), - endInclusive(false) { } - - Interval::Interval(BSONObj base, bool si, bool ei) { - init(base, si, ei); - } - - void Interval::init(BSONObj base, bool si, bool ei) { - verify(base.nFields() >= 2); - - _intervalData = base.getOwned(); - BSONObjIterator it(_intervalData); - start = it.next(); - end = it.next(); - startInclusive = si; - endInclusive = ei; +using std::string; + +Interval::Interval() + : _intervalData(BSONObj()), + start(BSONElement()), + startInclusive(false), + end(BSONElement()), + endInclusive(false) {} + +Interval::Interval(BSONObj base, bool si, bool ei) { + init(base, si, ei); +} + +void Interval::init(BSONObj base, bool si, bool ei) { + verify(base.nFields() >= 2); + + _intervalData = base.getOwned(); + BSONObjIterator it(_intervalData); + start = it.next(); + end = it.next(); + startInclusive = si; + endInclusive = ei; +} + +bool Interval::isEmpty() const { + return _intervalData.nFields() == 0; +} + +bool Interval::isPoint() const { + return startInclusive && endInclusive && 0 == start.woCompare(end, false); +} + +bool Interval::isNull() const { + return (!startInclusive || !endInclusive) && 0 == start.woCompare(end, false); +} + +// +// Comparison +// + +bool Interval::equals(const Interval& other) const { + if (this->startInclusive != other.startInclusive) { + return false; } - bool Interval::isEmpty() const { - return _intervalData.nFields() == 0; + if (this->endInclusive != other.endInclusive) { + return false; } - bool Interval::isPoint() const { - return startInclusive && endInclusive && 0 == start.woCompare(end, false); + int res = this->start.woCompare(other.start, false); + if (res != 0) { + return false; } - bool Interval::isNull() const { - return (!startInclusive || !endInclusive) && 0 == start.woCompare(end, false); + res = this->end.woCompare(other.end, false); + if (res != 0) { + return false; } - // - // Comparison - // - - bool Interval::equals(const Interval& other) const { - if (this->startInclusive != other.startInclusive) { - return false; - } + return true; +} - if (this->endInclusive != other.endInclusive) { - return false; - } +bool Interval::intersects(const Interval& other) const { + int res = this->start.woCompare(other.end, false); + if (res > 0) { + return false; + } else if (res == 0 && (!this->startInclusive || !other.endInclusive)) { + return false; + } - int res = this->start.woCompare(other.start, false); - if (res != 0) { - return false; - } + res = other.start.woCompare(this->end, false); + if (res > 0) { + return false; + } else if (res == 0 && (!other.startInclusive || !this->endInclusive)) { + return false; + } - res = this->end.woCompare(other.end, false); - if (res != 0) { - return false; - } + return true; +} - return true; +bool Interval::within(const Interval& other) const { + int res = this->start.woCompare(other.start, false); + if (res < 0) { + return false; + } else if (res == 0 && this->startInclusive && !other.startInclusive) { + return false; } - bool Interval::intersects(const Interval& other) const { - int res = this->start.woCompare(other.end, false); - if (res > 0) { - return false; - } - else if (res == 0 && (!this->startInclusive || !other.endInclusive)) { - return false; - } + res = this->end.woCompare(other.end, false); + if (res > 0) { + return false; + } else if (res == 0 && this->endInclusive && !other.endInclusive) { + return false; + } - res = other.start.woCompare(this->end, false); - if (res > 0) { - return false; - } - else if (res == 0 && (!other.startInclusive || !this->endInclusive)) { - return false; - } + return true; +} +/** Returns true if the start of comes before the start of other */ +bool Interval::precedes(const Interval& other) const { + int res = this->start.woCompare(other.start, false); + if (res < 0) { + return true; + } else if (res == 0 && this->startInclusive && !other.startInclusive) { return true; } + return false; +} - bool Interval::within(const Interval& other) const { - int res = this->start.woCompare(other.start, false); - if (res < 0) { - return false; - } - else if (res == 0 && this->startInclusive && !other.startInclusive) { - return false; - } - - res = this->end.woCompare(other.end, false); - if (res > 0) { - return false; - } - else if (res == 0 && this->endInclusive && !other.endInclusive) { - return false; - } - return true; - } +Interval::IntervalComparison Interval::compare(const Interval& other) const { + // + // Intersect cases + // - /** Returns true if the start of comes before the start of other */ - bool Interval::precedes(const Interval& other) const { - int res = this->start.woCompare(other.start, false); - if (res < 0) { - return true; + if (this->intersects(other)) { + if (this->equals(other)) { + return INTERVAL_EQUALS; } - else if (res == 0 && this->startInclusive && !other.startInclusive) { - return true; + if (this->within(other)) { + return INTERVAL_WITHIN; } - return false; - } - - - Interval::IntervalComparison Interval::compare(const Interval& other) const { - // - // Intersect cases - // - - if (this->intersects(other)) { - if (this->equals(other)) { - return INTERVAL_EQUALS; - } - if (this->within(other)) { - return INTERVAL_WITHIN; - } - if (other.within(*this)) { - return INTERVAL_CONTAINS; - } - if (this->precedes(other)) { - return INTERVAL_OVERLAPS_BEFORE; - } - return INTERVAL_OVERLAPS_AFTER; + if (other.within(*this)) { + return INTERVAL_CONTAINS; } - - // - // Non-intersect cases - // - if (this->precedes(other)) { - // It's not possible for both endInclusive and other.startInclusive to be true because - // the bounds would intersect. Refer to section on "Intersect cases" above. - if ((endInclusive || other.startInclusive) && 0 == end.woCompare(other.start, false)) { - return INTERVAL_PRECEDES_COULD_UNION; - } - return INTERVAL_PRECEDES; + return INTERVAL_OVERLAPS_BEFORE; } - - return INTERVAL_SUCCEEDS; + return INTERVAL_OVERLAPS_AFTER; } // - // Mutation: Union and Intersection + // Non-intersect cases // - void Interval::intersect(const Interval& other, IntervalComparison cmp) { - if (cmp == INTERVAL_UNKNOWN) { - cmp = this->compare(other); + if (this->precedes(other)) { + // It's not possible for both endInclusive and other.startInclusive to be true because + // the bounds would intersect. Refer to section on "Intersect cases" above. + if ((endInclusive || other.startInclusive) && 0 == end.woCompare(other.start, false)) { + return INTERVAL_PRECEDES_COULD_UNION; } + return INTERVAL_PRECEDES; + } - BSONObjBuilder builder; - switch (cmp) { + return INTERVAL_SUCCEEDS; +} +// +// Mutation: Union and Intersection +// + +void Interval::intersect(const Interval& other, IntervalComparison cmp) { + if (cmp == INTERVAL_UNKNOWN) { + cmp = this->compare(other); + } + + BSONObjBuilder builder; + switch (cmp) { case INTERVAL_EQUALS: case INTERVAL_WITHIN: break; @@ -220,17 +217,16 @@ namespace mongo { default: verify(false); - } } +} - void Interval::combine(const Interval& other, IntervalComparison cmp) { - if (cmp == INTERVAL_UNKNOWN) { - cmp = this->compare(other); - } - - BSONObjBuilder builder; - switch (cmp) { +void Interval::combine(const Interval& other, IntervalComparison cmp) { + if (cmp == INTERVAL_UNKNOWN) { + cmp = this->compare(other); + } + BSONObjBuilder builder; + switch (cmp) { case INTERVAL_EQUALS: case INTERVAL_CONTAINS: break; @@ -257,62 +253,62 @@ namespace mongo { default: verify(false); - } - } - - void Interval::reverse() { - std::swap(start, end); - std::swap(startInclusive, endInclusive); } +} - // - // Debug info - // +void Interval::reverse() { + std::swap(start, end); + std::swap(startInclusive, endInclusive); +} - // static - string Interval::cmpstr(IntervalComparison c) { - if (c == INTERVAL_EQUALS) { - return "INTERVAL_EQUALS"; - } +// +// Debug info +// - // 'this' contains the other interval. - if (c == INTERVAL_CONTAINS) { - return "INTERVAL_CONTAINS"; - } +// static +string Interval::cmpstr(IntervalComparison c) { + if (c == INTERVAL_EQUALS) { + return "INTERVAL_EQUALS"; + } - // 'this' is contained by the other interval. - if (c == INTERVAL_WITHIN) { - return "INTERVAL_WITHIN"; - } + // 'this' contains the other interval. + if (c == INTERVAL_CONTAINS) { + return "INTERVAL_CONTAINS"; + } - // The two intervals intersect and 'this' is before the other interval. - if (c == INTERVAL_OVERLAPS_BEFORE) { - return "INTERVAL_OVERLAPS_BEFORE"; - } + // 'this' is contained by the other interval. + if (c == INTERVAL_WITHIN) { + return "INTERVAL_WITHIN"; + } - // The two intervals intersect and 'this is after the other interval. - if (c == INTERVAL_OVERLAPS_AFTER) { - return "INTERVAL_OVERLAPS_AFTER"; - } + // The two intervals intersect and 'this' is before the other interval. + if (c == INTERVAL_OVERLAPS_BEFORE) { + return "INTERVAL_OVERLAPS_BEFORE"; + } - // There is no intersection. - if (c == INTERVAL_PRECEDES) { - return "INTERVAL_PRECEDES"; - } + // The two intervals intersect and 'this is after the other interval. + if (c == INTERVAL_OVERLAPS_AFTER) { + return "INTERVAL_OVERLAPS_AFTER"; + } - if (c == INTERVAL_PRECEDES_COULD_UNION) { - return "INTERVAL_PRECEDES_COULD_UNION"; - } + // There is no intersection. + if (c == INTERVAL_PRECEDES) { + return "INTERVAL_PRECEDES"; + } - if (c == INTERVAL_SUCCEEDS) { - return "INTERVAL_SUCCEEDS"; - } + if (c == INTERVAL_PRECEDES_COULD_UNION) { + return "INTERVAL_PRECEDES_COULD_UNION"; + } - if (c == INTERVAL_UNKNOWN) { - return "INTERVAL_UNKNOWN"; - } + if (c == INTERVAL_SUCCEEDS) { + return "INTERVAL_SUCCEEDS"; + } - return "NO IDEA DUDE"; + if (c == INTERVAL_UNKNOWN) { + return "INTERVAL_UNKNOWN"; } -} // namespace mongo + return "NO IDEA DUDE"; +} + +} // namespace mongo |