summaryrefslogtreecommitdiff
path: root/src/mongo/db/field_ref_set.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/field_ref_set.cpp')
-rw-r--r--src/mongo/db/field_ref_set.cpp208
1 files changed, 102 insertions, 106 deletions
diff --git a/src/mongo/db/field_ref_set.cpp b/src/mongo/db/field_ref_set.cpp
index efc49f2dd1d..4b46cf50b2b 100644
--- a/src/mongo/db/field_ref_set.cpp
+++ b/src/mongo/db/field_ref_set.cpp
@@ -33,129 +33,125 @@
namespace mongo {
- using std::vector;
- using std::string;
- namespace str = mongoutils::str;
-
- namespace {
-
- // For legacy purposes, we must handle empty fieldnames, which FieldRef clearly
- // prohibits. It is preferrable to have FieldRef keep that constraint and relax it here
- // -- stricly in update code. The rationale is that, if we want to ban data with no
- // field names, we must allow that data to be updated.
- StringData safeFirstPart(const FieldRef* fieldRef) {
- if (fieldRef->numParts() == 0) {
- return StringData();
- }
- else {
- return fieldRef->getPart(0);
- }
- }
-
+using std::vector;
+using std::string;
+namespace str = mongoutils::str;
+
+namespace {
+
+// For legacy purposes, we must handle empty fieldnames, which FieldRef clearly
+// prohibits. It is preferrable to have FieldRef keep that constraint and relax it here
+// -- stricly in update code. The rationale is that, if we want to ban data with no
+// field names, we must allow that data to be updated.
+StringData safeFirstPart(const FieldRef* fieldRef) {
+ if (fieldRef->numParts() == 0) {
+ return StringData();
+ } else {
+ return fieldRef->getPart(0);
}
+}
+}
- bool FieldRefSet::FieldRefPtrLessThan::operator()(const FieldRef* l, const FieldRef* r) const {
- return *l < *r;
- }
+bool FieldRefSet::FieldRefPtrLessThan::operator()(const FieldRef* l, const FieldRef* r) const {
+ return *l < *r;
+}
- FieldRefSet::FieldRefSet() {
- }
+FieldRefSet::FieldRefSet() {}
- FieldRefSet::FieldRefSet(const vector<FieldRef*>& paths) {
- fillFrom(paths);
- }
+FieldRefSet::FieldRefSet(const vector<FieldRef*>& paths) {
+ fillFrom(paths);
+}
- bool FieldRefSet::findConflicts(const FieldRef* toCheck, FieldRefSet* conflicts) const {
- bool foundConflict = false;
+bool FieldRefSet::findConflicts(const FieldRef* toCheck, FieldRefSet* conflicts) const {
+ bool foundConflict = false;
- // If the set is empty, there is no work to do.
- if (_fieldSet.empty())
- return foundConflict;
+ // If the set is empty, there is no work to do.
+ if (_fieldSet.empty())
+ return foundConflict;
- StringData prefixStr = safeFirstPart(toCheck);
- FieldRef prefixField(prefixStr);
+ StringData prefixStr = safeFirstPart(toCheck);
+ FieldRef prefixField(prefixStr);
- FieldSet::iterator it = _fieldSet.lower_bound(&prefixField);
- // Now, iterate over all the present fields in the set that have the same prefix.
+ FieldSet::iterator it = _fieldSet.lower_bound(&prefixField);
+ // Now, iterate over all the present fields in the set that have the same prefix.
- while (it != _fieldSet.end() && safeFirstPart(*it) == prefixStr) {
- size_t common = (*it)->commonPrefixSize(*toCheck);
- if ((*it)->numParts() == common || toCheck->numParts() == common) {
- if (!conflicts)
- return true;
+ while (it != _fieldSet.end() && safeFirstPart(*it) == prefixStr) {
+ size_t common = (*it)->commonPrefixSize(*toCheck);
+ if ((*it)->numParts() == common || toCheck->numParts() == common) {
+ if (!conflicts)
+ return true;
- conflicts->_fieldSet.insert(*it);
- foundConflict = true;
- }
- ++it;
+ conflicts->_fieldSet.insert(*it);
+ foundConflict = true;
}
-
- return foundConflict;
+ ++it;
}
- void FieldRefSet::keepShortest(const FieldRef* toInsert) {
- const FieldRef* conflict;
- if ( !insert(toInsert, &conflict) && (toInsert->numParts() < (conflict->numParts()))) {
- _fieldSet.erase(conflict);
- keepShortest(toInsert);
- }
- }
+ return foundConflict;
+}
- void FieldRefSet::fillFrom(const std::vector<FieldRef*>& fields) {
- dassert(_fieldSet.empty());
- _fieldSet.insert(fields.begin(), fields.end());
+void FieldRefSet::keepShortest(const FieldRef* toInsert) {
+ const FieldRef* conflict;
+ if (!insert(toInsert, &conflict) && (toInsert->numParts() < (conflict->numParts()))) {
+ _fieldSet.erase(conflict);
+ keepShortest(toInsert);
}
-
- bool FieldRefSet::insert(const FieldRef* toInsert, const FieldRef** conflict) {
-
- // We can determine if two fields conflict by checking their common prefix.
- //
- // If each field is exactly of the size of the common prefix, this means the fields are
- // the same. If one of the fields is greater than the common prefix and the other
- // isn't, the latter is a prefix of the former. And vice-versa.
- //
- // Example:
- //
- // inserted > | a a.c
- // exiting v | (0) (+1)
- // ----------------|------------------------
- // a (0) | equal prefix <
- // a.b (+1) | prefix ^ *
- //
- // * Disjoint sub-trees
-
- // At each insertion, we only need to bother checking the fields in the set that have
- // at least some common prefix with the 'toInsert' field.
- StringData prefixStr = safeFirstPart(toInsert);
- FieldRef prefixField(prefixStr);
- FieldSet::iterator it = _fieldSet.lower_bound(&prefixField);
-
- // Now, iterate over all the present fields in the set that have the same prefix.
- while (it != _fieldSet.end() && safeFirstPart(*it) == prefixStr) {
- size_t common = (*it)->commonPrefixSize(*toInsert);
- if ((*it)->numParts() == common || toInsert->numParts() == common) {
- *conflict = *it;
- return false;
- }
- ++it;
+}
+
+void FieldRefSet::fillFrom(const std::vector<FieldRef*>& fields) {
+ dassert(_fieldSet.empty());
+ _fieldSet.insert(fields.begin(), fields.end());
+}
+
+bool FieldRefSet::insert(const FieldRef* toInsert, const FieldRef** conflict) {
+ // We can determine if two fields conflict by checking their common prefix.
+ //
+ // If each field is exactly of the size of the common prefix, this means the fields are
+ // the same. If one of the fields is greater than the common prefix and the other
+ // isn't, the latter is a prefix of the former. And vice-versa.
+ //
+ // Example:
+ //
+ // inserted > | a a.c
+ // exiting v | (0) (+1)
+ // ----------------|------------------------
+ // a (0) | equal prefix <
+ // a.b (+1) | prefix ^ *
+ //
+ // * Disjoint sub-trees
+
+ // At each insertion, we only need to bother checking the fields in the set that have
+ // at least some common prefix with the 'toInsert' field.
+ StringData prefixStr = safeFirstPart(toInsert);
+ FieldRef prefixField(prefixStr);
+ FieldSet::iterator it = _fieldSet.lower_bound(&prefixField);
+
+ // Now, iterate over all the present fields in the set that have the same prefix.
+ while (it != _fieldSet.end() && safeFirstPart(*it) == prefixStr) {
+ size_t common = (*it)->commonPrefixSize(*toInsert);
+ if ((*it)->numParts() == common || toInsert->numParts() == common) {
+ *conflict = *it;
+ return false;
}
-
- _fieldSet.insert(it, toInsert);
- *conflict = NULL;
- return true;
+ ++it;
}
- const std::string FieldRefSet::toString() const {
- str::stream res;
- res << "Fields:[ ";
- FieldRefSet::const_iterator where = _fieldSet.begin();
- const FieldRefSet::const_iterator end = _fieldSet.end();
- for( ; where != end; ++where ) {
- const FieldRef& current = **where;
- res << current.dottedField() << ",";
- }
- res << "]";
- return res;
+ _fieldSet.insert(it, toInsert);
+ *conflict = NULL;
+ return true;
+}
+
+const std::string FieldRefSet::toString() const {
+ str::stream res;
+ res << "Fields:[ ";
+ FieldRefSet::const_iterator where = _fieldSet.begin();
+ const FieldRefSet::const_iterator end = _fieldSet.end();
+ for (; where != end; ++where) {
+ const FieldRef& current = **where;
+ res << current.dottedField() << ",";
}
+ res << "]";
+ return res;
+}
-} // namespace mongo
+} // namespace mongo