summaryrefslogtreecommitdiff
path: root/src/mongo/bson/util/builder.h
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2020-03-05 12:59:37 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-03-09 23:20:55 +0000
commit4994a4809269c30a28cdbb686c8c876fad7b163a (patch)
tree0e6a62253edbf6449eb85d6b6783ee0211d00e63 /src/mongo/bson/util/builder.h
parent83b4367daba1395aaf09f157db7edff3b2fd7431 (diff)
downloadmongo-4994a4809269c30a28cdbb686c8c876fad7b163a.tar.gz
SERVER-44095 Initialize TypeBits buffer to a smaller size
This lowers the memory overhead of index key generation by reducing the initial buffer size in TypeBits from 512 to 8 bytes.
Diffstat (limited to 'src/mongo/bson/util/builder.h')
-rw-r--r--src/mongo/bson/util/builder.h31
1 files changed, 24 insertions, 7 deletions
diff --git a/src/mongo/bson/util/builder.h b/src/mongo/bson/util/builder.h
index a6c821c5b0f..64b578faafd 100644
--- a/src/mongo/bson/util/builder.h
+++ b/src/mongo/bson/util/builder.h
@@ -111,6 +111,8 @@ private:
SharedBuffer _buf;
};
+enum { StackSizeDefault = 512 };
+template <size_t SZ>
class StackAllocator {
StackAllocator(const StackAllocator&) = delete;
StackAllocator& operator=(const StackAllocator&) = delete;
@@ -121,7 +123,6 @@ public:
free();
}
- enum { SZ = 512 };
void malloc(size_t sz) {
if (sz > SZ)
_ptr = mongoMalloc(sz);
@@ -340,7 +341,21 @@ private:
DataView(grow(sizeof(t))).write(tagLittleEndian(t));
}
/* "slow" portion of 'grow()' */
- void grow_reallocate(int minSize);
+ void grow_reallocate(int minSize) {
+ if (minSize > BufferMaxSize) {
+ std::stringstream ss;
+ ss << "BufBuilder attempted to grow() to " << minSize << " bytes, past the 64MB limit.";
+ msgasserted(13548, ss.str().c_str());
+ }
+
+ int a = 64;
+ while (a < minSize)
+ a = a * 2;
+
+ _buf.realloc(a);
+ size = a;
+ }
+
BufferAllocator _buf;
int l;
@@ -360,11 +375,13 @@ MONGO_STATIC_ASSERT(std::is_move_constructible_v<BufBuilder>);
nothing bad would happen. In fact in some circumstances this might make sense, say,
embedded in some other object.
*/
-class StackBufBuilder : public BasicBufBuilder<StackAllocator> {
+template <size_t SZ>
+class StackBufBuilderBase : public BasicBufBuilder<StackAllocator<SZ>> {
public:
- StackBufBuilder() : BasicBufBuilder<StackAllocator>(StackAllocator::SZ) {}
+ StackBufBuilderBase() : BasicBufBuilder<StackAllocator<SZ>>(SZ) {}
void release() = delete; // not allowed. not implemented.
};
+using StackBufBuilder = StackBufBuilderBase<StackSizeDefault>;
MONGO_STATIC_ASSERT(!std::is_move_constructible<StackBufBuilder>::value);
/** std::stringstream deals with locale so this is a lot faster than std::stringstream for UTF8 */
@@ -524,11 +541,11 @@ private:
};
using StringBuilder = StringBuilderImpl<SharedBufferAllocator>;
-using StackStringBuilder = StringBuilderImpl<StackAllocator>;
+using StackStringBuilder = StringBuilderImpl<StackAllocator<StackSizeDefault>>;
extern template class BasicBufBuilder<SharedBufferAllocator>;
-extern template class BasicBufBuilder<StackAllocator>;
+extern template class BasicBufBuilder<StackAllocator<StackSizeDefault>>;
extern template class StringBuilderImpl<SharedBufferAllocator>;
-extern template class StringBuilderImpl<StackAllocator>;
+extern template class StringBuilderImpl<StackAllocator<StackSizeDefault>>;
} // namespace mongo