diff options
author | James Wahlin <james.wahlin@10gen.com> | 2016-11-09 14:14:40 -0500 |
---|---|---|
committer | James Wahlin <james.wahlin@10gen.com> | 2016-11-15 14:49:34 -0500 |
commit | e0b312bbe4f2c50470560b92fbcfbdd3e0471d2f (patch) | |
tree | 1c9a133f1f9c6f6f0cf61fee8af3eacff5ee0329 /src/mongo/db/pipeline/field_path.h | |
parent | c55f35b894f145d14e7f3b4b431f4139c80a3778 (diff) | |
download | mongo-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.h | 64 |
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; }; } |