diff options
author | Mathias Stearn <mathias@10gen.com> | 2013-05-29 18:31:51 -0400 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2013-06-18 12:51:15 -0400 |
commit | be4e909ad1ae382a073f456710052a65c2b5fd39 (patch) | |
tree | 97fcb4fe336664c5651d262b5965baafa593d6fa /src/mongo/db | |
parent | f71dfdc67408a2fc0d695f865ad3abbb116ed443 (diff) | |
download | mongo-be4e909ad1ae382a073f456710052a65c2b5fd39.tar.gz |
Add Value::consume() to create an Array-typed Value without copying
Currently few places construct arrays, but more are coming soon. Note
that this can't be used for things like $push's getValue() since that
can be called multiple times so the array needs to be preserved.
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/pipeline/document.h | 2 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/pipeline/document_source_sort.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/pipeline/expression.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/pipeline/value.h | 12 |
5 files changed, 17 insertions, 5 deletions
diff --git a/src/mongo/db/pipeline/document.h b/src/mongo/db/pipeline/document.h index 375cd48faa3..77c04bafb3f 100644 --- a/src/mongo/db/pipeline/document.h +++ b/src/mongo/db/pipeline/document.h @@ -467,7 +467,7 @@ namespace mongo { return *this << Value(val); } - Value done() { return Value(_array); } + Value done() { return Value::consume(_array); } private: vector<Value> _array; diff --git a/src/mongo/db/pipeline/document_source.cpp b/src/mongo/db/pipeline/document_source.cpp index 6c46604e1ba..32a4ced05b9 100644 --- a/src/mongo/db/pipeline/document_source.cpp +++ b/src/mongo/db/pipeline/document_source.cpp @@ -167,7 +167,7 @@ namespace mongo { } } - return Value(values); + return Value::consume(values); } Document DocumentSource::documentFromBsonWithDeps(const BSONObj& bson, diff --git a/src/mongo/db/pipeline/document_source_sort.cpp b/src/mongo/db/pipeline/document_source_sort.cpp index 20e7948af4c..08ea0e85dd6 100644 --- a/src/mongo/db/pipeline/document_source_sort.cpp +++ b/src/mongo/db/pipeline/document_source_sort.cpp @@ -286,7 +286,7 @@ namespace mongo { for (size_t i=0; i < sp.size(); i++) { keys.push_back(sp[i]->evaluate(d)); } - key = Value(keys); + key = Value::consume(keys); } int DocumentSourceSort::compare(const KeyAndDoc & lhs, const KeyAndDoc & rhs) const { diff --git a/src/mongo/db/pipeline/expression.cpp b/src/mongo/db/pipeline/expression.cpp index c5b45981f72..3c5a52ddea7 100644 --- a/src/mongo/db/pipeline/expression.cpp +++ b/src/mongo/db/pipeline/expression.cpp @@ -1118,7 +1118,7 @@ namespace mongo { result.push_back(doc.freezeToValue()); } - out.addField(field.first, Value(result)); + out.addField(field.first, Value::consume(result)); } else { verify( false ); @@ -1300,7 +1300,7 @@ namespace mongo { result.push_back(nested); } - return Value(result); + return Value::consume(result); } Value ExpressionFieldPath::evaluatePath(size_t index, const Document& input) const { // Note this function is very hot so it is important that is is well optimized. diff --git a/src/mongo/db/pipeline/value.h b/src/mongo/db/pipeline/value.h index 26113876265..86cb7fa570c 100644 --- a/src/mongo/db/pipeline/value.h +++ b/src/mongo/db/pipeline/value.h @@ -97,6 +97,16 @@ namespace mongo { */ static Value createIntOrLong(long long value); + /** Construct an Array-typed Value from consumed without copying the vector. + * consumed is replaced with an empty vector. + * In C++11 this would be spelled Value(std::move(consumed)). + */ + static Value consume(vector<Value>& consumed) { + RCVector* vec = new RCVector(); + std::swap(vec->vec, consumed); + return Value(ValueStorage(Array, vec)); + } + /** A "missing" value indicates the lack of a Value. * This is similar to undefined/null but should not appear in output to BSON. * Missing Values are returned by Document when accessing non-existent fields. @@ -233,6 +243,8 @@ namespace mongo { template <typename InvalidArgumentType> explicit Value(const InvalidArgumentType& invalidArgument); + explicit Value(const ValueStorage& storage) :_storage(storage) {} + // does no type checking StringData getStringData() const; // May contain embedded NUL bytes |