summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2013-05-29 18:31:51 -0400
committerMathias Stearn <mathias@10gen.com>2013-06-18 12:51:15 -0400
commitbe4e909ad1ae382a073f456710052a65c2b5fd39 (patch)
tree97fcb4fe336664c5651d262b5965baafa593d6fa /src
parentf71dfdc67408a2fc0d695f865ad3abbb116ed443 (diff)
downloadmongo-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')
-rw-r--r--src/mongo/db/pipeline/document.h2
-rw-r--r--src/mongo/db/pipeline/document_source.cpp2
-rw-r--r--src/mongo/db/pipeline/document_source_sort.cpp2
-rw-r--r--src/mongo/db/pipeline/expression.cpp4
-rw-r--r--src/mongo/db/pipeline/value.h12
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