diff options
Diffstat (limited to 'src/mongo/bson/bsonmisc.h')
-rw-r--r-- | src/mongo/bson/bsonmisc.h | 475 |
1 files changed, 246 insertions, 229 deletions
diff --git a/src/mongo/bson/bsonmisc.h b/src/mongo/bson/bsonmisc.h index 3c9e5259161..baa7abad5e7 100644 --- a/src/mongo/bson/bsonmisc.h +++ b/src/mongo/bson/bsonmisc.h @@ -34,254 +34,271 @@ namespace mongo { - int getGtLtOp(const BSONElement& e); +int getGtLtOp(const BSONElement& e); - struct BSONElementCmpWithoutField { - bool operator()( const BSONElement &l, const BSONElement &r ) const { - return l.woCompare( r, false ) < 0; - } - }; - - class BSONObjCmp { - public: - BSONObjCmp( const BSONObj &order = BSONObj() ) : _order( order ) {} - bool operator()( const BSONObj &l, const BSONObj &r ) const { - return l.woCompare( r, _order ) < 0; - } - BSONObj order() const { return _order; } - private: - BSONObj _order; - }; - - typedef std::set<BSONObj,BSONObjCmp> BSONObjSet; - - enum FieldCompareResult { - LEFT_SUBFIELD = -2, - LEFT_BEFORE = -1, - SAME = 0, - RIGHT_BEFORE = 1 , - RIGHT_SUBFIELD = 2 - }; - - /** Use BSON macro to build a BSONObj from a stream - - e.g., - BSON( "name" << "joe" << "age" << 33 ) - - with auto-generated object id: - BSON( GENOID << "name" << "joe" << "age" << 33 ) - - The labels GT, GTE, LT, LTE, NE can be helpful for stream-oriented construction - of a BSONObj, particularly when assembling a Query. For example, - BSON( "a" << GT << 23.4 << NE << 30 << "b" << 2 ) produces the object - { a: { \$gt: 23.4, \$ne: 30 }, b: 2 }. - */ -#define BSON(x) (( ::mongo::BSONObjBuilder(64) << x ).obj()) +struct BSONElementCmpWithoutField { + bool operator()(const BSONElement& l, const BSONElement& r) const { + return l.woCompare(r, false) < 0; + } +}; - /** Use BSON_ARRAY macro like BSON macro, but without keys +class BSONObjCmp { +public: + BSONObjCmp(const BSONObj& order = BSONObj()) : _order(order) {} + bool operator()(const BSONObj& l, const BSONObj& r) const { + return l.woCompare(r, _order) < 0; + } + BSONObj order() const { + return _order; + } - BSONArray arr = BSON_ARRAY( "hello" << 1 << BSON( "foo" << BSON_ARRAY( "bar" << "baz" << "qux" ) ) ); +private: + BSONObj _order; +}; - */ -#define BSON_ARRAY(x) (( ::mongo::BSONArrayBuilder() << x ).arr()) +typedef std::set<BSONObj, BSONObjCmp> BSONObjSet; - /* Utility class to auto assign object IDs. - Example: - std::cout << BSON( GENOID << "z" << 3 ); // { _id : ..., z : 3 } - */ - struct GENOIDLabeler { }; - extern GENOIDLabeler GENOID; +enum FieldCompareResult { + LEFT_SUBFIELD = -2, + LEFT_BEFORE = -1, + SAME = 0, + RIGHT_BEFORE = 1, + RIGHT_SUBFIELD = 2 +}; - /* Utility class to add a Date element with the current time - Example: - std::cout << BSON( "created" << DATENOW ); // { created : "2009-10-09 11:41:42" } - */ - struct DateNowLabeler { }; - extern DateNowLabeler DATENOW; +/** Use BSON macro to build a BSONObj from a stream - /* Utility class to assign a NULL value to a given attribute - Example: - std::cout << BSON( "a" << BSONNULL ); // { a : null } - */ - struct NullLabeler { }; - extern NullLabeler BSONNULL; + e.g., + BSON( "name" << "joe" << "age" << 33 ) - /* Utility class to assign an Undefined value to a given attribute - Example: - std::cout << BSON( "a" << BSONUndefined ); // { a : undefined } - */ - struct UndefinedLabeler { }; - extern UndefinedLabeler BSONUndefined; + with auto-generated object id: + BSON( GENOID << "name" << "joe" << "age" << 33 ) - /* Utility class to add the minKey (minus infinity) to a given attribute - Example: - std::cout << BSON( "a" << MINKEY ); // { "a" : { "$minKey" : 1 } } - */ - struct MinKeyLabeler { }; - extern MinKeyLabeler MINKEY; - struct MaxKeyLabeler { }; - extern MaxKeyLabeler MAXKEY; - - // Utility class to implement GT, GTE, etc as described above. - class Labeler { - public: - struct Label { - explicit Label( const char *l ) : l_( l ) {} - const char *l_; - }; - Labeler( const Label &l, BSONObjBuilderValueStream *s ) : l_( l ), s_( s ) {} - template<class T> - BSONObjBuilder& operator<<( T value ); - - /* the value of the element e is appended i.e. for - "age" << GT << someElement - one gets - { age : { $gt : someElement's value } } - */ - BSONObjBuilder& operator<<( const BSONElement& e ); - private: - const Label &l_; - BSONObjBuilderValueStream *s_; - }; + The labels GT, GTE, LT, LTE, NE can be helpful for stream-oriented construction + of a BSONObj, particularly when assembling a Query. For example, + BSON( "a" << GT << 23.4 << NE << 30 << "b" << 2 ) produces the object + { a: { \$gt: 23.4, \$ne: 30 }, b: 2 }. +*/ +#define BSON(x) ((::mongo::BSONObjBuilder(64) << x).obj()) - // Utility class to allow adding a std::string to BSON as a Symbol - struct BSONSymbol { - explicit BSONSymbol(StringData sym) :symbol(sym) {} - StringData symbol; - }; - - // Utility class to allow adding a std::string to BSON as Code - struct BSONCode { - explicit BSONCode(StringData str) :code(str) {} - StringData code; - }; +/** Use BSON_ARRAY macro like BSON macro, but without keys - // Utility class to allow adding CodeWScope to BSON - struct BSONCodeWScope { - explicit BSONCodeWScope(StringData str, const BSONObj& obj) :code(str), scope(obj) {} - StringData code; - BSONObj scope; - }; - - // Utility class to allow adding a RegEx to BSON - struct BSONRegEx { - explicit BSONRegEx(StringData pat, StringData f="") :pattern(pat), flags(f) {} - StringData pattern; - StringData flags; - }; + BSONArray arr = BSON_ARRAY( "hello" << 1 << BSON( "foo" << BSON_ARRAY( "bar" << "baz" << "qux" ) ) ); - // Utility class to allow adding binary data to BSON - struct BSONBinData { - BSONBinData(const void* d, int l, BinDataType t) :data(d), length(l), type(t) {} - const void* data; - int length; - BinDataType type; - }; - - // Utility class to allow adding deprecated DBRef type to BSON - struct BSONDBRef { - BSONDBRef(StringData nameSpace, const OID& o) :ns(nameSpace), oid(o) {} - StringData ns; - OID oid; + */ +#define BSON_ARRAY(x) ((::mongo::BSONArrayBuilder() << x).arr()) + +/* Utility class to auto assign object IDs. + Example: + std::cout << BSON( GENOID << "z" << 3 ); // { _id : ..., z : 3 } +*/ +struct GENOIDLabeler {}; +extern GENOIDLabeler GENOID; + +/* Utility class to add a Date element with the current time + Example: + std::cout << BSON( "created" << DATENOW ); // { created : "2009-10-09 11:41:42" } +*/ +struct DateNowLabeler {}; +extern DateNowLabeler DATENOW; + +/* Utility class to assign a NULL value to a given attribute + Example: + std::cout << BSON( "a" << BSONNULL ); // { a : null } +*/ +struct NullLabeler {}; +extern NullLabeler BSONNULL; + +/* Utility class to assign an Undefined value to a given attribute + Example: + std::cout << BSON( "a" << BSONUndefined ); // { a : undefined } +*/ +struct UndefinedLabeler {}; +extern UndefinedLabeler BSONUndefined; + +/* Utility class to add the minKey (minus infinity) to a given attribute + Example: + std::cout << BSON( "a" << MINKEY ); // { "a" : { "$minKey" : 1 } } +*/ +struct MinKeyLabeler {}; +extern MinKeyLabeler MINKEY; +struct MaxKeyLabeler {}; +extern MaxKeyLabeler MAXKEY; + +// Utility class to implement GT, GTE, etc as described above. +class Labeler { +public: + struct Label { + explicit Label(const char* l) : l_(l) {} + const char* l_; }; + Labeler(const Label& l, BSONObjBuilderValueStream* s) : l_(l), s_(s) {} + template <class T> + BSONObjBuilder& operator<<(T value); + + /* the value of the element e is appended i.e. for + "age" << GT << someElement + one gets + { age : { $gt : someElement's value } } + */ + BSONObjBuilder& operator<<(const BSONElement& e); + +private: + const Label& l_; + BSONObjBuilderValueStream* s_; +}; + +// Utility class to allow adding a std::string to BSON as a Symbol +struct BSONSymbol { + explicit BSONSymbol(StringData sym) : symbol(sym) {} + StringData symbol; +}; + +// Utility class to allow adding a std::string to BSON as Code +struct BSONCode { + explicit BSONCode(StringData str) : code(str) {} + StringData code; +}; + +// Utility class to allow adding CodeWScope to BSON +struct BSONCodeWScope { + explicit BSONCodeWScope(StringData str, const BSONObj& obj) : code(str), scope(obj) {} + StringData code; + BSONObj scope; +}; + +// Utility class to allow adding a RegEx to BSON +struct BSONRegEx { + explicit BSONRegEx(StringData pat, StringData f = "") : pattern(pat), flags(f) {} + StringData pattern; + StringData flags; +}; + +// Utility class to allow adding binary data to BSON +struct BSONBinData { + BSONBinData(const void* d, int l, BinDataType t) : data(d), length(l), type(t) {} + const void* data; + int length; + BinDataType type; +}; + +// Utility class to allow adding deprecated DBRef type to BSON +struct BSONDBRef { + BSONDBRef(StringData nameSpace, const OID& o) : ns(nameSpace), oid(o) {} + StringData ns; + OID oid; +}; + +extern Labeler::Label GT; +extern Labeler::Label GTE; +extern Labeler::Label LT; +extern Labeler::Label LTE; +extern Labeler::Label NE; +extern Labeler::Label NIN; +extern Labeler::Label BSIZE; + + +// $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT << 6)); +// becomes : {$or: [{x: {$gt: 7}}, {y: {$lt: 6}}]} +inline BSONObj OR(const BSONObj& a, const BSONObj& b); +inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c); +inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d); +inline BSONObj OR( + const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e); +inline BSONObj OR(const BSONObj& a, + const BSONObj& b, + const BSONObj& c, + const BSONObj& d, + const BSONObj& e, + const BSONObj& f); +// definitions in bsonobjbuilder.h b/c of incomplete types + +// Utility class to implement BSON( key << val ) as described above. +class BSONObjBuilderValueStream { + MONGO_DISALLOW_COPYING(BSONObjBuilderValueStream); + +public: + friend class Labeler; + BSONObjBuilderValueStream(BSONObjBuilder* builder); + + BSONObjBuilder& operator<<(const BSONElement& e); + + template <class T> + BSONObjBuilder& operator<<(T value); + + BSONObjBuilder& operator<<(const DateNowLabeler& id); + + BSONObjBuilder& operator<<(const NullLabeler& id); + BSONObjBuilder& operator<<(const UndefinedLabeler& id); + + BSONObjBuilder& operator<<(const MinKeyLabeler& id); + BSONObjBuilder& operator<<(const MaxKeyLabeler& id); + + Labeler operator<<(const Labeler::Label& l); + + void endField(StringData nextFieldName = StringData()); + bool subobjStarted() const { + return _fieldName != 0; + } + + // The following methods provide API compatibility with BSONArrayBuilder + BufBuilder& subobjStart(); + BufBuilder& subarrayStart(); + + // This method should only be called from inside of implementations of + // BSONObjBuilder& operator<<(BSONObjBuilderValueStream&, SOME_TYPE) + // to provide the return value. + BSONObjBuilder& builder() { + return *_builder; + } + +private: + StringData _fieldName; + BSONObjBuilder* _builder; + + bool haveSubobj() const { + return _subobj.get() != 0; + } + BSONObjBuilder* subobj(); + std::unique_ptr<BSONObjBuilder> _subobj; +}; + +/** + used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage + */ +class BSONSizeTracker { +public: + BSONSizeTracker() { + _pos = 0; + for (int i = 0; i < SIZE; i++) + _sizes[i] = 512; // this is the default, so just be consistent + } - extern Labeler::Label GT; - extern Labeler::Label GTE; - extern Labeler::Label LT; - extern Labeler::Label LTE; - extern Labeler::Label NE; - extern Labeler::Label NIN; - extern Labeler::Label BSIZE; - - - // $or helper: OR(BSON("x" << GT << 7), BSON("y" << LT << 6)); - // becomes : {$or: [{x: {$gt: 7}}, {y: {$lt: 6}}]} - inline BSONObj OR(const BSONObj& a, const BSONObj& b); - inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c); - inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d); - inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e); - inline BSONObj OR(const BSONObj& a, const BSONObj& b, const BSONObj& c, const BSONObj& d, const BSONObj& e, const BSONObj& f); - // definitions in bsonobjbuilder.h b/c of incomplete types - - // Utility class to implement BSON( key << val ) as described above. - class BSONObjBuilderValueStream { - MONGO_DISALLOW_COPYING(BSONObjBuilderValueStream); - public: - friend class Labeler; - BSONObjBuilderValueStream( BSONObjBuilder * builder ); - - BSONObjBuilder& operator<<( const BSONElement& e ); - - template<class T> - BSONObjBuilder& operator<<( T value ); - - BSONObjBuilder& operator<<(const DateNowLabeler& id); - - BSONObjBuilder& operator<<(const NullLabeler& id); - BSONObjBuilder& operator<<(const UndefinedLabeler& id); - - BSONObjBuilder& operator<<(const MinKeyLabeler& id); - BSONObjBuilder& operator<<(const MaxKeyLabeler& id); - - Labeler operator<<( const Labeler::Label &l ); - - void endField( StringData nextFieldName = StringData() ); - bool subobjStarted() const { return _fieldName != 0; } - - // The following methods provide API compatibility with BSONArrayBuilder - BufBuilder& subobjStart(); - BufBuilder& subarrayStart(); - - // This method should only be called from inside of implementations of - // BSONObjBuilder& operator<<(BSONObjBuilderValueStream&, SOME_TYPE) - // to provide the return value. - BSONObjBuilder& builder() { return *_builder; } - private: - StringData _fieldName; - BSONObjBuilder * _builder; + ~BSONSizeTracker() {} - bool haveSubobj() const { return _subobj.get() != 0; } - BSONObjBuilder *subobj(); - std::unique_ptr< BSONObjBuilder > _subobj; - }; + void got(int size) { + _sizes[_pos] = size; + _pos = (_pos + 1) % SIZE; // thread safe at least on certain compilers + } /** - used in conjuction with BSONObjBuilder, allows for proper buffer size to prevent crazy memory usage + * right now choosing largest size */ - class BSONSizeTracker { - public: - BSONSizeTracker() { - _pos = 0; - for ( int i=0; i<SIZE; i++ ) - _sizes[i] = 512; // this is the default, so just be consistent - } - - ~BSONSizeTracker() { - } - - void got( int size ) { - _sizes[_pos] = size; - _pos = (_pos + 1) % SIZE; // thread safe at least on certain compilers + int getSize() const { + int x = 16; // sane min + for (int i = 0; i < SIZE; i++) { + if (_sizes[i] > x) + x = _sizes[i]; } + return x; + } - /** - * right now choosing largest size - */ - int getSize() const { - int x = 16; // sane min - for ( int i=0; i<SIZE; i++ ) { - if ( _sizes[i] > x ) - x = _sizes[i]; - } - return x; - } - - private: - enum { SIZE = 10 }; - int _pos; - int _sizes[SIZE]; - }; +private: + enum { SIZE = 10 }; + int _pos; + int _sizes[SIZE]; +}; - // considers order - bool fieldsMatch(const BSONObj& lhs, const BSONObj& rhs); +// considers order +bool fieldsMatch(const BSONObj& lhs, const BSONObj& rhs); } |