diff options
author | Antonin Kral <a.kral@bobek.cz> | 2011-03-17 00:07:52 +0100 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2011-03-17 00:07:52 +0100 |
commit | 98b8b639326ab4c89eed73739d9903993c4c8959 (patch) | |
tree | 0462df078bf740093774d033b75f0ea24a31fa97 /bson/util | |
parent | f5d6e97ca8d2f3e7c4cdd5c9afbf8e756ef65bc2 (diff) | |
parent | 582fc32574a3b158c81e49cb00e6ae59205e66ba (diff) | |
download | mongodb-98b8b639326ab4c89eed73739d9903993c4c8959.tar.gz |
Merge commit 'upstream/1.8.0
Diffstat (limited to 'bson/util')
-rw-r--r-- | bson/util/atomic_int.h | 40 | ||||
-rw-r--r-- | bson/util/builder.h | 149 | ||||
-rw-r--r-- | bson/util/misc.h | 4 |
3 files changed, 110 insertions, 83 deletions
diff --git a/bson/util/atomic_int.h b/bson/util/atomic_int.h index f4d2749..1573552 100644 --- a/bson/util/atomic_int.h +++ b/bson/util/atomic_int.h @@ -24,51 +24,55 @@ namespace mongo { - struct AtomicUInt{ + struct AtomicUInt { AtomicUInt() : x(0) {} AtomicUInt(unsigned z) : x(z) { } - volatile unsigned x; - operator unsigned() const { - return x; - } + + operator unsigned() const { return x; } + unsigned get() const { return x; } + inline AtomicUInt operator++(); // ++prefix inline AtomicUInt operator++(int);// postfix++ inline AtomicUInt operator--(); // --prefix inline AtomicUInt operator--(int); // postfix-- + + inline void zero() { x = 0; } // TODO: this isn't thread safe + + volatile unsigned x; }; #if defined(_WIN32) - AtomicUInt AtomicUInt::operator++(){ + AtomicUInt AtomicUInt::operator++() { // InterlockedIncrement returns the new value return InterlockedIncrement((volatile long*)&x); //long is 32bits in Win64 } - AtomicUInt AtomicUInt::operator++(int){ + AtomicUInt AtomicUInt::operator++(int) { return InterlockedIncrement((volatile long*)&x)-1; } - AtomicUInt AtomicUInt::operator--(){ + AtomicUInt AtomicUInt::operator--() { return InterlockedDecrement((volatile long*)&x); } - AtomicUInt AtomicUInt::operator--(int){ + AtomicUInt AtomicUInt::operator--(int) { return InterlockedDecrement((volatile long*)&x)+1; } #elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) // this is in GCC >= 4.1 - AtomicUInt AtomicUInt::operator++(){ + AtomicUInt AtomicUInt::operator++() { return __sync_add_and_fetch(&x, 1); } - AtomicUInt AtomicUInt::operator++(int){ + AtomicUInt AtomicUInt::operator++(int) { return __sync_fetch_and_add(&x, 1); } - AtomicUInt AtomicUInt::operator--(){ + AtomicUInt AtomicUInt::operator--() { return __sync_add_and_fetch(&x, -1); } - AtomicUInt AtomicUInt::operator--(int){ + AtomicUInt AtomicUInt::operator--(int) { return __sync_fetch_and_add(&x, -1); } #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) // from boost 1.39 interprocess/detail/atomic.hpp - inline unsigned atomic_int_helper(volatile unsigned *x, int val){ + inline unsigned atomic_int_helper(volatile unsigned *x, int val) { int r; asm volatile ( @@ -80,16 +84,16 @@ namespace mongo { ); return r; } - AtomicUInt AtomicUInt::operator++(){ + AtomicUInt AtomicUInt::operator++() { return atomic_int_helper(&x, 1)+1; } - AtomicUInt AtomicUInt::operator++(int){ + AtomicUInt AtomicUInt::operator++(int) { return atomic_int_helper(&x, 1); } - AtomicUInt AtomicUInt::operator--(){ + AtomicUInt AtomicUInt::operator--() { return atomic_int_helper(&x, -1)-1; } - AtomicUInt AtomicUInt::operator--(int){ + AtomicUInt AtomicUInt::operator--(int) { return atomic_int_helper(&x, -1); } #else diff --git a/bson/util/builder.h b/bson/util/builder.h index 9d9eda2..6f4ff9e 100644 --- a/bson/util/builder.h +++ b/bson/util/builder.h @@ -27,6 +27,24 @@ namespace mongo { + /* Note the limit here is rather arbitrary and is simply a standard. generally the code works + with any object that fits in ram. + + Also note that the server has some basic checks to enforce this limit but those checks are not exhaustive + for example need to check for size too big after + update $push (append) operation + various db.eval() type operations + */ + const int BSONObjMaxUserSize = 16 * 1024 * 1024; + + /* + Sometimeswe we need objects slightly larger - an object in the replication local.oplog + is slightly larger than a user object for example. + */ + const int BSONObjMaxInternalSize = BSONObjMaxUserSize + ( 16 * 1024 ); + + const int BufferMaxSize = 64 * 1024 * 1024; + class StringBuilder; void msgasserted(int msgid, const char *msg); @@ -38,7 +56,8 @@ namespace mongo { data = (char *) malloc(size); if( data == 0 ) msgasserted(10000, "out of memory BufBuilder"); - } else { + } + else { data = 0; } l = 0; @@ -54,16 +73,18 @@ namespace mongo { } } - void reset( int maxSize = 0 ){ + void reset( int maxSize = 0 ) { l = 0; - if ( maxSize && size > maxSize ){ + if ( maxSize && size > maxSize ) { free(data); data = (char*)malloc(maxSize); size = maxSize; - } + } } - /* leave room for some stuff later */ + /** leave room for some stuff later + @return point to region that was skipped. pointer may change later (on realloc), so for immediate use only + */ char* skip(int n) { return grow(n); } /* note this may be deallocated (realloced) if you keep writing. */ @@ -73,10 +94,10 @@ namespace mongo { /* assume ownership of the buffer - you must then free() it */ void decouple() { data = 0; } - void appendChar(char j){ + void appendChar(char j) { *((char*)grow(sizeof(char))) = j; } - void appendNum(char j){ + void appendNum(char j) { *((char*)grow(sizeof(char))) = j; } void appendNum(short j) { @@ -105,18 +126,19 @@ namespace mongo { memcpy(grow((int) len), src, len); } + template<class T> + void appendStruct(const T& s) { + appendBuf(&s, sizeof(T)); + } + void appendStr(const StringData &str , bool includeEOO = true ) { const int len = str.size() + ( includeEOO ? 1 : 0 ); memcpy(grow(len), str.data(), len); } - int len() const { - return l; - } - - void setlen( int newLen ){ - l = newLen; - } + int len() const { return l; } + void setlen( int newLen ) { l = newLen; } + int getSize() const { return size; } /* returns the pre-grow write position */ inline char* grow(int by) { @@ -128,18 +150,16 @@ namespace mongo { return data + oldlen; } - int getSize() const { return size; } - private: /* "slow" portion of 'grow()' */ - void NOINLINE_DECL grow_reallocate(){ + void NOINLINE_DECL grow_reallocate() { int a = size * 2; if ( a == 0 ) a = 512; if ( l > a ) a = l + 16 * 1024; - if( a > 64 * 1024 * 1024 ) - msgasserted(10000, "BufBuilder grow() > 64MB"); + if ( a > BufferMaxSize ) + msgasserted(13548, "BufBuilder grow() > 64MB"); data = (char *) realloc(data, a); size= a; } @@ -152,87 +172,90 @@ namespace mongo { }; #if defined(_WIN32) +#pragma warning( push ) +// warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. #pragma warning( disable : 4996 ) #endif + /** stringstream deals with locale so this is a lot faster than std::stringstream for UTF8 */ class StringBuilder { public: StringBuilder( int initsize=256 ) - : _buf( initsize ){ + : _buf( initsize ) { } -#define SBNUM(val,maxSize,macro) \ - int prev = _buf.l; \ - int z = sprintf( _buf.grow(maxSize) , macro , (val) ); \ - assert( z >= 0 ); \ - _buf.l = prev + z; \ - return *this; - - StringBuilder& operator<<( double x ){ - SBNUM( x , 25 , "%g" ); + StringBuilder& operator<<( double x ) { + return SBNUM( x , 25 , "%g" ); } - StringBuilder& operator<<( int x ){ - SBNUM( x , 11 , "%d" ); + StringBuilder& operator<<( int x ) { + return SBNUM( x , 11 , "%d" ); } - StringBuilder& operator<<( unsigned x ){ - SBNUM( x , 11 , "%u" ); + StringBuilder& operator<<( unsigned x ) { + return SBNUM( x , 11 , "%u" ); } - StringBuilder& operator<<( long x ){ - SBNUM( x , 22 , "%ld" ); + StringBuilder& operator<<( long x ) { + return SBNUM( x , 22 , "%ld" ); } - StringBuilder& operator<<( unsigned long x ){ - SBNUM( x , 22 , "%lu" ); + StringBuilder& operator<<( unsigned long x ) { + return SBNUM( x , 22 , "%lu" ); } - StringBuilder& operator<<( long long x ){ - SBNUM( x , 22 , "%lld" ); + StringBuilder& operator<<( long long x ) { + return SBNUM( x , 22 , "%lld" ); } - StringBuilder& operator<<( unsigned long long x ){ - SBNUM( x , 22 , "%llu" ); + StringBuilder& operator<<( unsigned long long x ) { + return SBNUM( x , 22 , "%llu" ); } - StringBuilder& operator<<( short x ){ - SBNUM( x , 8 , "%hd" ); + StringBuilder& operator<<( short x ) { + return SBNUM( x , 8 , "%hd" ); } - StringBuilder& operator<<( char c ){ + StringBuilder& operator<<( char c ) { _buf.grow( 1 )[0] = c; return *this; } -#undef SBNUM - void appendDoubleNice( double x ){ + void appendDoubleNice( double x ) { int prev = _buf.l; char * start = _buf.grow( 32 ); int z = sprintf( start , "%.16g" , x ); assert( z >= 0 ); _buf.l = prev + z; - if( strchr(start, '.') == 0 && strchr(start, 'E') == 0 && strchr(start, 'N') == 0 ){ + if( strchr(start, '.') == 0 && strchr(start, 'E') == 0 && strchr(start, 'N') == 0 ) { write( ".0" , 2 ); } } - void write( const char* buf, int len){ - memcpy( _buf.grow( len ) , buf , len ); - } + void write( const char* buf, int len) { memcpy( _buf.grow( len ) , buf , len ); } - void append( const StringData& str ){ - memcpy( _buf.grow( str.size() ) , str.data() , str.size() ); - } - StringBuilder& operator<<( const StringData& str ){ + void append( const StringData& str ) { memcpy( _buf.grow( str.size() ) , str.data() , str.size() ); } + + StringBuilder& operator<<( const StringData& str ) { append( str ); return *this; } - - // access - void reset( int maxSize = 0 ){ - _buf.reset( maxSize ); - } - - std::string str(){ - return std::string(_buf.data, _buf.l); - } + void reset( int maxSize = 0 ) { _buf.reset( maxSize ); } + + std::string str() const { return std::string(_buf.data, _buf.l); } private: BufBuilder _buf; + + // non-copyable, non-assignable + StringBuilder( const StringBuilder& ); + StringBuilder& operator=( const StringBuilder& ); + + template <typename T> + StringBuilder& SBNUM(T val,int maxSize,const char *macro) { + int prev = _buf.l; + int z = sprintf( _buf.grow(maxSize) , macro , (val) ); + assert( z >= 0 ); + _buf.l = prev + z; + return *this; + } }; +#if defined(_WIN32) +#pragma warning( pop ) +#endif + } // namespace mongo diff --git a/bson/util/misc.h b/bson/util/misc.h index cad9a28..b31f36f 100644 --- a/bson/util/misc.h +++ b/bson/util/misc.h @@ -34,7 +34,7 @@ namespace mongo { buf[24] = 0; // don't want the \n } - inline string time_t_to_String(time_t t = time(0) ){ + inline string time_t_to_String(time_t t = time(0) ) { char buf[64]; #if defined(_WIN32) ctime_s(buf, sizeof(buf), &t); @@ -76,7 +76,7 @@ namespace mongo { Date_t(unsigned long long m): millis(m) {} operator unsigned long long&() { return millis; } operator const unsigned long long&() const { return millis; } - string toString() const { + string toString() const { char buf[64]; time_t_to_String(millis/1000, buf); return buf; |