diff options
author | Andrew Morrow <acm@10gen.com> | 2013-08-19 12:45:49 -0400 |
---|---|---|
committer | Andrew Morrow <acm@10gen.com> | 2013-09-12 12:10:27 -0400 |
commit | 917adade854b8301e5956d37093db02b1a248070 (patch) | |
tree | 3edabbae7cb318d73d4e479c31dc07d0c22826bf /src/mongo/db/field_ref.cpp | |
parent | a6177c60770d8612bf13118b72be2ecdcd23f0fc (diff) | |
download | mongo-917adade854b8301e5956d37093db02b1a248070.tar.gz |
SERVER-10159 Retain concatenated dotted path and return it that way when possible.
Diffstat (limited to 'src/mongo/db/field_ref.cpp')
-rw-r--r-- | src/mongo/db/field_ref.cpp | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/src/mongo/db/field_ref.cpp b/src/mongo/db/field_ref.cpp index 5a04ebeb082..2b09e2ee011 100644 --- a/src/mongo/db/field_ref.cpp +++ b/src/mongo/db/field_ref.cpp @@ -45,24 +45,23 @@ namespace mongo { } // We guarantee that accesses through getPart() will be valid while 'this' is. So we - // take a copy. We're going to be "chopping" up the copy into c-strings. - _fieldBase.reset(new char[dottedField.size()+1]); - dottedField.copyTo( _fieldBase.get(), true ); + // keep a copy in a local sting. + + _dotted = dottedField.toString(); // Separate the field parts using '.' as a delimiter. - char* beg = _fieldBase.get(); - char* cur = beg; - char* end = beg + dottedField.size(); + std::string::iterator beg = _dotted.begin(); + std::string::iterator cur = beg; + const std::string::iterator end = _dotted.end(); while (true) { if (cur != end && *cur != '.') { cur++; continue; } - appendPart(StringData(beg, cur - beg)); + appendPart(StringData(&*beg, cur - beg)); if (cur != end) { - *cur = '\0'; beg = ++cur; continue; } @@ -142,19 +141,27 @@ namespace mongo { } std::string FieldRef::dottedField( size_t offset ) const { - std::string res; + std::string result; if (_size == 0 || offset >= numParts() ) { - return res; + // fall through, we will return the empty string. } - - for (size_t i=offset; i<_size; i++) { - if ( i > offset ) - res.append(1, '.'); - StringData part = getPart(i); - res.append(part.rawData(), part.size()); + else if (_replacements.empty() && (offset == 0)) { + result = _dotted; } - return res; + else { + // Reserve some space in the string. We know we will have, at minimum, a character + // for each component we are writing, and a dot for each component, less one. + result.reserve(((_size - offset) * 2) - 1); + for (size_t i=offset; i<_size; i++) { + if ( i > offset ) + result.append(1, '.'); + StringData part = getPart(i); + result.append(part.rawData(), part.size()); + } + } + + return result; } bool FieldRef::equalsDottedField( const StringData& other ) const { @@ -208,7 +215,7 @@ namespace mongo { void FieldRef::clear() { _size = 0; _variable.clear(); - _fieldBase.reset(); + _dotted.clear(); _replacements.clear(); } |