summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/field_path.h
diff options
context:
space:
mode:
authorJames Wahlin <james.wahlin@10gen.com>2016-11-09 14:14:40 -0500
committerJames Wahlin <james.wahlin@10gen.com>2016-11-15 14:49:34 -0500
commite0b312bbe4f2c50470560b92fbcfbdd3e0471d2f (patch)
tree1c9a133f1f9c6f6f0cf61fee8af3eacff5ee0329 /src/mongo/db/pipeline/field_path.h
parentc55f35b894f145d14e7f3b4b431f4139c80a3778 (diff)
downloadmongo-e0b312bbe4f2c50470560b92fbcfbdd3e0471d2f.tar.gz
SERVER-26964 Make FieldPath more efficient
Diffstat (limited to 'src/mongo/db/pipeline/field_path.h')
-rw-r--r--src/mongo/db/pipeline/field_path.h64
1 files changed, 25 insertions, 39 deletions
diff --git a/src/mongo/db/pipeline/field_path.h b/src/mongo/db/pipeline/field_path.h
index 8ac025f899e..2a93e607078 100644
--- a/src/mongo/db/pipeline/field_path.h
+++ b/src/mongo/db/pipeline/field_path.h
@@ -28,7 +28,6 @@
#pragma once
-#include <iosfwd>
#include <string>
#include <vector>
@@ -57,11 +56,7 @@ public:
* Returns the substring of 'path' until the first '.', or the entire string if there is no '.'.
*/
static StringData extractFirstFieldFromDottedPath(StringData path) {
- const auto firstDot = path.find('.');
- if (firstDot == std::string::npos) {
- return path;
- }
- return path.substr(0, firstDot);
+ return path.substr(0, path.find('.'));
}
/**
@@ -69,67 +64,58 @@ public:
*
* Field names are validated using uassertValidFieldName().
*/
- FieldPath(const std::string& fieldPath);
-
- /**
- * Throws a UserException if 'fieldNames' is empty or if any of the field names fail validation.
- *
- * Field names are validated using uassertValidFieldName().
- */
- FieldPath(const std::vector<std::string>& fieldNames);
+ /* implicit */ FieldPath(std::string inputPath);
+ /* implicit */ FieldPath(StringData inputPath) : FieldPath(inputPath.toString()) {}
+ /* implicit */ FieldPath(const char* inputPath) : FieldPath(std::string(inputPath)) {}
/**
* Returns the number of path elements in the field path.
*/
size_t getPathLength() const {
- return _fieldNames.size();
+ return _fieldPathDotPosition.size() - 1;
}
/**
* Return the ith field name from this path using zero-based indexes.
*/
- const std::string& getFieldName(size_t i) const {
+ StringData getFieldName(size_t i) const {
dassert(i < getPathLength());
- return _fieldNames[i];
+ const auto begin = _fieldPathDotPosition[i] + 1;
+ const auto end = _fieldPathDotPosition[i + 1];
+ return StringData(&_fieldPath[begin], end - begin);
}
/**
* Returns the full path, not including the prefix 'FieldPath::prefix'.
*/
- std::string fullPath() const;
+ const std::string& fullPath() const {
+ return _fieldPath;
+ }
/**
* Returns the full path, including the prefix 'FieldPath::prefix'.
*/
- std::string fullPathWithPrefix() const;
-
- /**
- * Write the full path to 'outStream', including the prefix 'FieldPath::prefix' if
- * 'includePrefix' is specified.
- */
- void writePath(std::ostream& outStream, bool includePrefix) const;
-
- static const char* getPrefix() {
- return prefix;
+ std::string fullPathWithPrefix() const {
+ return prefix + _fieldPath;
}
-
/**
* A FieldPath like this but missing the first element (useful for recursion).
* Precondition getPathLength() > 1.
*/
- FieldPath tail() const;
+ FieldPath tail() const {
+ massert(16409, "FieldPath::tail() called on single element path", getPathLength() > 1);
+ return {_fieldPath.substr(_fieldPathDotPosition[1] + 1)};
+ }
private:
- /**
- * Push a new field name to the back of the vector of names comprising the field path.
- *
- * Throws a UserException if 'fieldName' does not pass validation done by
- * uassertValidFieldName().
- */
- void pushFieldName(const std::string& fieldName);
+ static const char prefix = '$';
- static const char prefix[];
+ // Contains the full field path, with each field delimited by a '.' character.
+ std::string _fieldPath;
- std::vector<std::string> _fieldNames;
+ // Contains the position of field delimiter dots in '_fieldPath'. The first element contains
+ // string::npos (which evaluates to -1) and the last contains _fieldPath.size() to facilitate
+ // lookup.
+ std::vector<size_t> _fieldPathDotPosition;
};
}