diff options
author | Alberto Lerner <alerner@10gen.com> | 2013-09-24 12:16:41 -0400 |
---|---|---|
committer | Alberto Lerner <alerner@10gen.com> | 2013-09-24 12:16:41 -0400 |
commit | e87726c246e50c05739bbb8f8ccfbb43384397ea (patch) | |
tree | 3df18cf5cf325f54211addbceb0b031421c640c3 /src | |
parent | 555cbd552bf404d4e9344fe19495fcb7a36e95ac (diff) | |
download | mongo-e87726c246e50c05739bbb8f8ccfbb43384397ea.tar.gz |
SERVER-10159 Embed some number of ElementReps in the Document.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/bson/mutable/document.cpp | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/mongo/bson/mutable/document.cpp b/src/mongo/bson/mutable/document.cpp index 1be6660dbd3..c4f9c2e3739 100644 --- a/src/mongo/bson/mutable/document.cpp +++ b/src/mongo/bson/mutable/document.cpp @@ -399,6 +399,9 @@ namespace mutablebson { // The designated field name for the root element. const char kRootFieldName[] = ""; + // How many reps do we cache before we spill to heap. Use a power of two. + const size_t kFastReps = 128; + // An ElementRep contains the information necessary to locate the data for an Element, // and the topology information for how the Element is related to other Elements in the // document. @@ -555,7 +558,8 @@ namespace mutablebson { public: Impl(Document::InPlaceMode inPlaceMode) - : _elements() + : _numElements(0) + , _slowElements() , _objects() , _fieldNames() , _leafBuf() @@ -577,7 +581,9 @@ namespace mutablebson { void reset(Document::InPlaceMode inPlaceMode) { // Clear out the state in the vectors. - _elements.clear(); + _slowElements.clear(); + _numElements = 0; + _objects.clear(); _fieldNames.clear(); @@ -597,25 +603,32 @@ namespace mutablebson { // Obtain the ElementRep for the given rep id. ElementRep& getElementRep(Element::RepIdx id) { - dassert(id < _elements.size()); - return _elements[id]; + return const_cast<ElementRep&>(const_cast<const Impl*>(this)->getElementRep(id)); } // Obtain the ElementRep for the given rep id. const ElementRep& getElementRep(Element::RepIdx id) const { - dassert(id < _elements.size()); - return _elements[id]; + dassert(id < _numElements); + if (id < kFastReps) + return _fastElements[id]; + else + return _slowElements[id - kFastReps]; } // Insert the given ElementRep and return an ID for it. Element::RepIdx insertElement(const ElementRep& rep) { - const Element::RepIdx id = _elements.size(); + const Element::RepIdx id = _numElements++; verify(id <= Element::kMaxRepIdx); - _elements.push_back(rep); - if (debug && paranoid) { - // Force all reps to new addresses to help catch invalid rep usage. - std::vector<ElementRep> new_elements(_elements); - _elements.swap(new_elements); + if (id < kFastReps) { + _fastElements[id] = rep; + } + else { + _slowElements.push_back(rep); + if (debug && paranoid) { + // Force all reps to new addresses to help catch invalid rep usage. + std::vector<ElementRep> newSlowElements(_slowElements); + _slowElements.swap(newSlowElements); + } } return id; } @@ -680,7 +693,7 @@ namespace mutablebson { // Retrieve the fieldName, given a rep. StringData getFieldName(const ElementRep& rep) const { // The root element has no field name. - if (&rep == &_elements[kRootRepIdx]) + if (&rep == &getElementRep(kRootRepIdx)) return StringData(); if (rep.serialized || (rep.objIdx != kInvalidObjIdx)) @@ -701,7 +714,7 @@ namespace mutablebson { // Retrieve the type, given a rep. BSONType getType(const ElementRep& rep) const { // The root element is always an Object. - if (&rep == &_elements[kRootRepIdx]) + if (&rep == &getElementRep(kRootRepIdx)) return mongo::Object; if (rep.serialized || (rep.objIdx != kInvalidObjIdx)) @@ -727,7 +740,7 @@ namespace mutablebson { bool hasValue(const ElementRep& rep) const { // The root element may be marked serialized, but it doesn't have a BSONElement // representation. - if (&rep == &_elements[kRootRepIdx]) + if (&rep == &getElementRep(kRootRepIdx)) return false; return rep.serialized; @@ -1006,7 +1019,10 @@ namespace mutablebson { return &_fieldNames[fieldNameId]; } - std::vector<ElementRep> _elements; + size_t _numElements; + ElementRep _fastElements[kFastReps]; + std::vector<ElementRep> _slowElements; + std::vector<BSONObj> _objects; std::vector<char> _fieldNames; |