From ac84841e638adcd03ccda7c97e940fb6cc6bdf5b Mon Sep 17 00:00:00 2001 From: Eliot Horowitz Date: Tue, 29 Dec 2009 17:32:31 -0500 Subject: [PATCH] first checking of simple/fast resettable StringBuilder --- db/curop.h | 6 ++++ db/instance.cpp | 4 +-- dbtests/basictests.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++ util/builder.h | 77 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 161 insertions(+), 3 deletions(-) diff --git a/db/curop.h b/db/curop.h index 926667b944e..c58719d1c3a 100644 --- a/db/curop.h +++ b/db/curop.h @@ -32,16 +32,22 @@ namespace mongo { return o; } + stringstream _debug; public: void reset( const sockaddr_in &_client) { _active = true; _opNum = _nextOpNum.atomicIncrement(); _timer.reset(); _ns[0] = '?'; // just in case not set later + _debug.rdbuf()->pubseekpos(0); resetQuery(); client = _client; } + stringstream& debugstream(){ + return _debug; + } + WrappingInt opNum() const { return _opNum; } bool active() const { return _active; } diff --git a/db/instance.cpp b/db/instance.cpp index 13973011484..04f4d93e894 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -257,12 +257,12 @@ namespace mongo { Client& c = cc(); c.clearns(); - stringstream ss; - CurOp& currentOp = *c.curop(); currentOp.reset( client); currentOp.setOp(op); + stringstream& ss = currentOp.debugstream(); + int logThreshold = cmdLine.slowMS; bool log = logLevel >= 1; diff --git a/dbtests/basictests.cpp b/dbtests/basictests.cpp index ff98b8a70d1..6d6ede07fc3 100644 --- a/dbtests/basictests.cpp +++ b/dbtests/basictests.cpp @@ -110,6 +110,78 @@ namespace BasicTests { roundTrip( y , 40 ); } }; + + namespace stringbuildertests { +#define SBTGB(x) ss << (x); sb << (x); + + class Base { + virtual void pop() = 0; + + public: + Base(){} + virtual ~Base(){} + + void run(){ + pop(); + ASSERT_EQUALS( ss.str() , sb.str() ); + } + + stringstream ss; + StringBuilder sb; + }; + + class simple1 : public Base { + void pop(){ + SBTGB(1); + SBTGB("yo"); + SBTGB(2); + } + }; + + class simple2 : public Base { + void pop(){ + SBTGB(1); + SBTGB("yo"); + SBTGB(2); + SBTGB( 12123123123LL ); + SBTGB( "xxx" ); + SBTGB( 5.4 ); + SBTGB( 5.4312 ); + SBTGB( "yyy" ); + SBTGB( (short)5 ); + SBTGB( (short)1231231231231 ); + } + }; + + class reset1 { + public: + void run(){ + StringBuilder sb; + sb << "1" << "abc" << "5.17"; + ASSERT_EQUALS( "1abc5.17" , sb.str() ); + ASSERT_EQUALS( "1abc5.17" , sb.str() ); + sb.reset(); + ASSERT_EQUALS( "" , sb.str() ); + sb << "999"; + ASSERT_EQUALS( "999" , sb.str() ); + } + }; + + class reset2 { + public: + void run(){ + StringBuilder sb; + sb << "1" << "abc" << "5.17"; + ASSERT_EQUALS( "1abc5.17" , sb.str() ); + ASSERT_EQUALS( "1abc5.17" , sb.str() ); + sb.reset(1); + ASSERT_EQUALS( "" , sb.str() ); + sb << "999"; + ASSERT_EQUALS( "999" , sb.str() ); + } + }; + + } class All : public Suite { public: @@ -119,6 +191,11 @@ namespace BasicTests { void setupTests(){ add< Rarely >(); add< Base64Tests >(); + + add< stringbuildertests::simple1 >(); + add< stringbuildertests::simple2 >(); + add< stringbuildertests::reset1 >(); + add< stringbuildertests::reset2 >(); } } myall; diff --git a/util/builder.h b/util/builder.h index d62ae43e010..a658aaee4da 100644 --- a/util/builder.h +++ b/util/builder.h @@ -17,10 +17,13 @@ #pragma once -#include "../stdafx.h" +#include "stdafx.h" +#include namespace mongo { + class StringBuilder; + class BufBuilder { public: BufBuilder(int initsize = 512) : size(initsize) { @@ -43,6 +46,16 @@ namespace mongo { } } + void reset( int maxSize = 0 ){ + l = 0; + if ( maxSize && size > maxSize ){ + free(data); + data = (char*)malloc(maxSize); + size = maxSize; + } + + } + /* leave room for some stuff later */ void skip(int n) { grow(n); @@ -118,6 +131,68 @@ namespace mongo { char *data; int l; int size; + + friend class StringBuilder; + }; + + class StringBuilder { + public: + StringBuilder( int initsize=256 ) + : _buf( initsize ){ + } + +#define SBNUM(val,maxSize,macro) \ + int prev = _buf.l; \ + int z = sprintf( _buf.grow(maxSize) , macro , (val) ); \ + _buf.l = prev + z; \ + return *this; + + + StringBuilder& operator<<( double x ){ + SBNUM( x , 25 , "%g" ); + } + StringBuilder& operator<<( int x ){ + SBNUM( x , 11 , "%d" ); + } + StringBuilder& operator<<( unsigned x ){ + SBNUM( x , 11 , "%u" ); + } + StringBuilder& operator<<( long x ){ + SBNUM( x , 22 , "%ld" ); + } + StringBuilder& operator<<( long long x ){ + SBNUM( x , 22 , "%lld" ); + } + StringBuilder& operator<<( short x ){ + SBNUM( x , 8 , "%hd" ); + } + + + void append( const char * str ){ + int x = strlen( str ); + memcpy( _buf.grow( x ) , str , x ); + } + StringBuilder& operator<<( const char * str ){ + append( str ); + return *this; + } + StringBuilder& operator<<( const string& s ){ + append( s.c_str() ); + return *this; + } + + // access + + void reset( int maxSize = 0 ){ + _buf.reset( maxSize ); + } + + string str(){ + return string(_buf.data,0,_buf.l); + } + + private: + BufBuilder _buf; }; } // namespace mongo