diff options
author | dwight <dwight@10gen.com> | 2011-05-10 12:40:01 -0400 |
---|---|---|
committer | dwight <dwight@10gen.com> | 2011-05-10 12:40:01 -0400 |
commit | 871d923401fd5c296564d81c10f20bb500858883 (patch) | |
tree | eb3a0825ea1a1c17d92e316a884b8739365b7954 /bson | |
parent | ce0dd5aec9e1214a8e7fad7f0547bdc6cfee5085 (diff) | |
download | mongo-871d923401fd5c296564d81c10f20bb500858883.tar.gz |
StackBufBuilder
Diffstat (limited to 'bson')
-rw-r--r-- | bson/inline_decls.h | 33 | ||||
-rw-r--r-- | bson/util/builder.h | 69 |
2 files changed, 73 insertions, 29 deletions
diff --git a/bson/inline_decls.h b/bson/inline_decls.h index 1605611687f..afe926c60e7 100644 --- a/bson/inline_decls.h +++ b/bson/inline_decls.h @@ -1,20 +1,19 @@ -// inline.h - -/** -* Copyright (C) 2010 10gen Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ +// inline_decls.h + +/* Copyright 2010 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #pragma once diff --git a/bson/util/builder.h b/bson/util/builder.h index a3dd09d4ce6..4c20b87ef0a 100644 --- a/bson/util/builder.h +++ b/bson/util/builder.h @@ -20,8 +20,6 @@ #include <string> #include <string.h> #include <stdio.h> -//#include <boost/shared_ptr.hpp> - #include "../inline_decls.h" #include "../stringdata.h" @@ -49,11 +47,44 @@ namespace mongo { void msgasserted(int msgid, const char *msg); - class BufBuilder { + class TrivialAllocator { public: - BufBuilder(int initsize = 512) : size(initsize) { + void* Malloc(size_t sz) { return malloc(sz); } + void* Realloc(void *p, size_t sz) { return realloc(p, sz); } + void Free(void *p) { free(p); } + }; + + class StackAllocator { + public: + enum { SZ = 512 }; + void* Malloc(size_t sz) { + if( sz <= SZ ) return buf; + return malloc(sz); + } + void* Realloc(void *p, size_t sz) { + if( p == buf ) { + if( sz <= SZ ) return buf; + void *d = malloc(sz); + memcpy(d, p, SZ); + return d; + } + return realloc(p, sz); + } + void Free(void *p) { + if( p != buf ) + free(p); + } + private: + char buf[SZ]; + }; + + template< class Allocator > + class _BufBuilder : boost::noncopyable { + Allocator al; + public: + _BufBuilder(int initsize = 512) : size(initsize) { if ( size > 0 ) { - data = (char *) malloc(size); + data = (char *) al.Malloc(size); if( data == 0 ) msgasserted(10000, "out of memory BufBuilder"); } @@ -62,13 +93,11 @@ namespace mongo { } l = 0; } - ~BufBuilder() { - kill(); - } + ~_BufBuilder() { kill(); } void kill() { if ( data ) { - free(data); + al.Free(data); data = 0; } } @@ -79,8 +108,8 @@ namespace mongo { void reset( int maxSize ) { l = 0; if ( maxSize && size > maxSize ) { - free(data); - data = (char*)malloc(maxSize); + al.Free(data); + data = (char*)al.Malloc(maxSize); size = maxSize; } } @@ -168,7 +197,7 @@ namespace mongo { a = l + 16 * 1024; if ( a > BufferMaxSize ) msgasserted(13548, "BufBuilder grow() > 64MB"); - data = (char *) realloc(data, a); + data = (char *) al.Realloc(data, a); size= a; } @@ -179,6 +208,22 @@ namespace mongo { friend class StringBuilder; }; + template class _BufBuilder<TrivialAllocator>; + typedef _BufBuilder<TrivialAllocator> BufBuilder; + + /** The StackBufBuilder builds smaller datasets on the stack instead of using malloc. + this can be significantly faster for small bufs. However, you can not decouple() the + buffer with StackBufBuilder. + While designed to be a variable on the stack, if you were to dynamically allocate one, + nothing bad would happen. In fact in some circumstances this might make sense, say, + embedded in some other object. + */ + class StackBufBuilder : public _BufBuilder<StackAllocator> { + public: + StackBufBuilder() : _BufBuilder<StackAllocator>(StackAllocator::SZ) { } + void decouple(); // not allowed. not implemented. + }; + #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. |