diff options
author | Alberto Lerner <alerner@10gen.com> | 2013-07-05 10:35:20 -0400 |
---|---|---|
committer | Alberto Lerner <alerner@10gen.com> | 2013-07-05 10:35:20 -0400 |
commit | 1961a5d66cee7d9bc102cc2ff6f189c4c4306895 (patch) | |
tree | 5afc1c935a7bf81a0edc3ef0e0da32f150429858 /src/mongo/db/field_ref.h | |
parent | 5f949c19a26099320f1040e875b3841d4a362b26 (diff) | |
download | mongo-1961a5d66cee7d9bc102cc2ff6f189c4c4306895.tar.gz |
SERVER-7175 Support for catching conflicting mods in the update driver.
Diffstat (limited to 'src/mongo/db/field_ref.h')
-rw-r--r-- | src/mongo/db/field_ref.h | 84 |
1 files changed, 61 insertions, 23 deletions
diff --git a/src/mongo/db/field_ref.h b/src/mongo/db/field_ref.h index ed3a110715b..e04497f7ae1 100644 --- a/src/mongo/db/field_ref.h +++ b/src/mongo/db/field_ref.h @@ -17,6 +17,7 @@ #pragma once #include <boost/scoped_array.hpp> +#include <iosfwd> #include <string> #include <vector> @@ -63,12 +64,34 @@ namespace mongo { StringData getPart(size_t i) const; /** + * Returns true when 'this' FieldRef is a prefix of 'other'. Equality is not considered + * a prefix. + */ + bool isPrefixOf( const FieldRef& other ) const; + + /** + * Returns the number of field parts in the prefix that 'this' and 'other' share. + */ + size_t commonPrefixSize( const FieldRef& other ) const; + + /** * Returns a copy of the full dotted field in its current state (i.e., some parts may * have been replaced since the parse() call). */ std::string dottedField( size_t offset = 0 ) const; /** + * Compares the full dotted path represented by this FieldRef to other + */ + bool equalsDottedField( const StringData& other ) const; + + /** + * Return 0 if 'this' is equal to 'other' lexicographically, -1 if is it less than or + * +1 if it is greater than. + */ + int compare( const FieldRef& other ) const; + + /** * Resets the internal state. See note in parse() call. */ void clear(); @@ -88,34 +111,13 @@ namespace mongo { */ size_t numReplaced() const; - /** - * Compares the full dotted path represented by this FieldRef to other - */ - bool equalsDottedField( const StringData& other ) const; - - /** - * Compares the full dotted path represented by this FieldRef to other, - * and that we are a prefix of them. - * - * Returns true when 'this' is a prefix of 'other'; equality is not considered a prefix. - */ - bool isPrefixOf( const FieldRef& other ) const; - private: - // Dotted fields are most often not longer than three parts. We use a mixed structure + // Dotted fields are most often not longer than four parts. We use a mixed structure // here that will not require any extra memory allocation when that is the case. And // handle larger dotted fields if it is. The idea is not to penalize the common case // with allocations. static const size_t kReserveAhead = 4; - size_t _size; // # of field parts stored - StringData _fixed[kReserveAhead]; // first kResevedAhead field components - std::vector<StringData> _variable; // remaining field components - - // Areas that _fixed and _variable point to. - boost::scoped_array<char> _fieldBase; // concatenation of null-terminated parts - std::vector<std::string> _replacements; // added with the setPart call - /** Converts the field part index to the variable part equivalent */ size_t getIndex(size_t i) const { return i-kReserveAhead; } @@ -125,10 +127,46 @@ namespace mongo { */ size_t appendPart(const StringData& part); + // number of field parts stored + size_t _size; + + // first kResevedAhead field components + StringData _fixed[kReserveAhead]; + + // remaining field components + std::vector<StringData> _variable; + + // concatenation of null-terminated parts pointed to by _fixed and _variable + boost::scoped_array<char> _fieldBase; + + // back memory added with the setPart call pointed to by _fized and _variable + std::vector<std::string> _replacements; }; inline bool operator==(const FieldRef& lhs, const FieldRef& rhs) { - return lhs.equalsDottedField(rhs.dottedField()); + return lhs.compare(rhs) == 0; + } + + inline bool operator!=(const FieldRef& lhs, const FieldRef& rhs) { + return lhs.compare(rhs) != 0; + } + + inline bool operator<(const FieldRef& lhs, const FieldRef& rhs) { + return lhs.compare(rhs) < 0; + } + + inline bool operator<=(const FieldRef& lhs, const FieldRef& rhs) { + return lhs.compare(rhs) <= 0; } + inline bool operator>(const FieldRef& lhs, const FieldRef& rhs) { + return lhs.compare(rhs) > 0; + } + + inline bool operator>=(const FieldRef& lhs, const FieldRef& rhs) { + return lhs.compare(rhs) >= 0; + } + + std::ostream& operator<<(std::ostream& stream, const FieldRef& value); + } // namespace mongo |