diff options
author | David Storch <david.storch@10gen.com> | 2015-11-13 13:28:36 -0500 |
---|---|---|
committer | David Storch <david.storch@10gen.com> | 2015-11-13 16:41:37 -0500 |
commit | 7a99fd808fc4e8960d2981799415617c495a0fda (patch) | |
tree | 89fbd9ea94559b27637e9d3d1a09827981622c19 /src/mongo/bson | |
parent | bddbae79b4733dbd392215c38beccab5daa0109c (diff) | |
download | mongo-7a99fd808fc4e8960d2981799415617c495a0fda.tar.gz |
SERVER-20853 eliminate copies in find and getMore path
Diffstat (limited to 'src/mongo/bson')
-rw-r--r-- | src/mongo/bson/bsonmisc.cpp | 5 | ||||
-rw-r--r-- | src/mongo/bson/bsonmisc.h | 5 | ||||
-rw-r--r-- | src/mongo/bson/bsonobjbuilder.h | 17 | ||||
-rw-r--r-- | src/mongo/bson/bsonobjbuilder_test.cpp | 17 |
4 files changed, 42 insertions, 2 deletions
diff --git a/src/mongo/bson/bsonmisc.cpp b/src/mongo/bson/bsonmisc.cpp index b106121b590..28e88690b29 100644 --- a/src/mongo/bson/bsonmisc.cpp +++ b/src/mongo/bson/bsonmisc.cpp @@ -72,6 +72,11 @@ BSONObjBuilderValueStream::BSONObjBuilderValueStream(BSONObjBuilder* builder) { _builder = builder; } +void BSONObjBuilderValueStream::reset() { + _fieldName = StringData(); + _subobj.reset(); +} + BSONObjBuilder& BSONObjBuilderValueStream::operator<<(const BSONElement& e) { _builder->appendAs(e, _fieldName); _fieldName = StringData(); diff --git a/src/mongo/bson/bsonmisc.h b/src/mongo/bson/bsonmisc.h index d1c1894190a..f32319965f1 100644 --- a/src/mongo/bson/bsonmisc.h +++ b/src/mongo/bson/bsonmisc.h @@ -253,6 +253,11 @@ public: return *_builder; } + /** + * Restores this object to its empty state. + */ + void reset(); + private: StringData _fieldName; BSONObjBuilder* _builder; diff --git a/src/mongo/bson/bsonobjbuilder.h b/src/mongo/bson/bsonobjbuilder.h index 5b744a62120..ed21c7b63e1 100644 --- a/src/mongo/bson/bsonobjbuilder.h +++ b/src/mongo/bson/bsonobjbuilder.h @@ -601,6 +601,20 @@ public: BSONObjBuilder& append(StringData fieldName, const std::map<K, T>& vals); /** + * Resets this BSONObjBulder to an empty state. All previously added fields are lost. If this + * BSONObjBuilder is using an externally provided BufBuilder, this method does not affect the + * bytes before the start of this object. + * + * Invalid to call if done() has already been called in order to finalize the BSONObj. + */ + void resetToEmpty() { + invariant(!_doneCalled); + _s.reset(); + // Reset the position the next write will go to right after our size reservation. + _b.setlen(_offset + sizeof(int)); + } + + /** * destructive * The returned BSONObj will free the buffer when it is finished. * @return owned BSONObj @@ -887,10 +901,9 @@ private: template <class T> inline BSONObjBuilder& BSONObjBuilder::append(StringData fieldName, const std::vector<T>& vals) { - BSONObjBuilder arrBuilder; + BSONObjBuilder arrBuilder(subarrayStart(fieldName)); for (unsigned int i = 0; i < vals.size(); ++i) arrBuilder.append(numStr(i), vals[i]); - appendArray(fieldName, arrBuilder.done()); return *this; } diff --git a/src/mongo/bson/bsonobjbuilder_test.cpp b/src/mongo/bson/bsonobjbuilder_test.cpp index d92d48d6098..fdee41b8ba1 100644 --- a/src/mongo/bson/bsonobjbuilder_test.cpp +++ b/src/mongo/bson/bsonobjbuilder_test.cpp @@ -303,4 +303,21 @@ TEST(BSONObjBuilderTest, ResumeBuildingWithNesting) { << "dd")) << "a" << BSON("c" << 3))); } +TEST(BSONObjBuilderTest, ResetToEmptyResultsInEmptyObj) { + BSONObjBuilder bob; + bob.append("a", 3); + bob.resetToEmpty(); + ASSERT_EQ(BSONObj(), bob.obj()); +} + +TEST(BSONObjBuilderTest, ResetToEmptyForNestedBuilderOnlyResetsInnerObj) { + BSONObjBuilder bob; + bob.append("a", 3); + BSONObjBuilder innerObj(bob.subobjStart("nestedObj")); + innerObj.append("b", 4); + innerObj.resetToEmpty(); + innerObj.done(); + ASSERT_EQ(BSON("a" << 3 << "nestedObj" << BSONObj()), bob.obj()); +} + } // unnamed namespace |