summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Morrow <acm@10gen.com>2013-09-23 20:38:38 -0400
committerAndrew Morrow <acm@10gen.com>2013-12-17 10:26:04 -0500
commitd73db8af612528d5dff98f0112a24edf36c085e6 (patch)
treec56e174d8ba964f5da976c0eca0e54626f925f0c /src
parent7b16d40afbc6320539cb1933b9e6a60d3db86607 (diff)
downloadmongo-d73db8af612528d5dff98f0112a24edf36c085e6.tar.gz
SERVER-10159 Cache field name lengths in mutable elements
Diffstat (limited to 'src')
-rw-r--r--src/mongo/bson/bsonelement.h13
-rw-r--r--src/mongo/bson/mutable/document.cpp25
2 files changed, 32 insertions, 6 deletions
diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h
index 753a89d2704..ffc018bfdc3 100644
--- a/src/mongo/bson/bsonelement.h
+++ b/src/mongo/bson/bsonelement.h
@@ -455,6 +455,19 @@ namespace mongo {
}
}
+ struct FieldNameSizeTag {}; // For disambiguation with ctor taking 'maxLen' above.
+
+ /** Construct a BSONElement where you already know the length of the name. The value
+ * passed here includes the null terminator. The data pointed to by 'd' must not
+ * represent an EOO. You may pass -1 to indicate that you don't actually know the
+ * size.
+ */
+ BSONElement(const char* d, int fieldNameSize, FieldNameSizeTag)
+ : data(d)
+ , fieldNameSize_(fieldNameSize) // internal size includes null terminator
+ , totalSize(-1) {
+ }
+
std::string _asCode() const;
OpTime _opTime() const;
diff --git a/src/mongo/bson/mutable/document.cpp b/src/mongo/bson/mutable/document.cpp
index 259a2f36330..ad4c43f13b1 100644
--- a/src/mongo/bson/mutable/document.cpp
+++ b/src/mongo/bson/mutable/document.cpp
@@ -449,10 +449,8 @@ namespace mutablebson {
// The index of our parent in the Document.
Element::RepIdx parent;
- // Pad this object out to 32 bytes.
- //
- // TODO: Cache element size here?
- uint32_t pad;
+ // The cached field name size of this element, or -1 if unknown.
+ int32_t fieldNameSize;
};
#pragma pack(pop)
@@ -609,7 +607,7 @@ namespace mutablebson {
{ Element::kInvalidRepIdx, Element::kInvalidRepIdx },
{ Element::kInvalidRepIdx, Element::kInvalidRepIdx },
Element::kInvalidRepIdx,
- 0
+ -1
};
const Element::RepIdx id = *newIdx = _numElements++;
@@ -679,7 +677,10 @@ namespace mutablebson {
// Given a RepIdx, return the BSONElement that it represents.
BSONElement getSerializedElement(const ElementRep& rep) const {
const BSONObj& object = getObject(rep.objIdx);
- return BSONElement(object.objdata() + rep.offset);
+ return BSONElement(
+ object.objdata() + rep.offset,
+ rep.fieldNameSize,
+ BSONElement::FieldNameSizeTag());
}
// A helper method that either inserts the field name into the field name heap and
@@ -765,6 +766,11 @@ namespace mutablebson {
getObject(rep->objIdx)).firstElement();
if (!childElt.eoo()) {
+
+ // Do this now before other writes so compiler can exploit knowing
+ // that we are not eoo.
+ const int32_t fieldNameSize = childElt.fieldNameSize();
+
Element::RepIdx inserted;
ElementRep& newRep = makeNewRep(&inserted);
// Calling makeNewRep invalidates rep since it may cause a reallocation of
@@ -782,6 +788,7 @@ namespace mutablebson {
newRep.child.left = Element::kOpaqueRepIdx;
newRep.child.right = Element::kOpaqueRepIdx;
}
+ newRep.fieldNameSize = fieldNameSize;
rep->child.left = inserted;
} else {
rep->child.left = Element::kInvalidRepIdx;
@@ -832,6 +839,11 @@ namespace mutablebson {
BSONElement rightElt(elt.rawdata() + elt.size());
if (!rightElt.eoo()) {
+
+ // Do this now before other writes so compiler can exploit knowing
+ // that we are not eoo.
+ const int32_t fieldNameSize = rightElt.fieldNameSize();
+
Element::RepIdx inserted;
ElementRep& newRep = makeNewRep(&inserted);
// Calling makeNewRep invalidates rep since it may cause a reallocation of
@@ -850,6 +862,7 @@ namespace mutablebson {
newRep.child.left = Element::kOpaqueRepIdx;
newRep.child.right = Element::kOpaqueRepIdx;
}
+ newRep.fieldNameSize = fieldNameSize;
rep->sibling.right = inserted;
} else {
rep->sibling.right = Element::kInvalidRepIdx;