summaryrefslogtreecommitdiff
path: root/src/mongo/db/field_ref.cpp
diff options
context:
space:
mode:
authorAndrew Morrow <acm@10gen.com>2013-08-19 12:45:49 -0400
committerAndrew Morrow <acm@10gen.com>2013-09-12 12:10:27 -0400
commit917adade854b8301e5956d37093db02b1a248070 (patch)
tree3edabbae7cb318d73d4e479c31dc07d0c22826bf /src/mongo/db/field_ref.cpp
parenta6177c60770d8612bf13118b72be2ecdcd23f0fc (diff)
downloadmongo-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.cpp43
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();
}