diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 00:22:50 -0400 |
---|---|---|
committer | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2015-06-20 10:56:02 -0400 |
commit | 9c2ed42daa8fbbef4a919c21ec564e2db55e8d60 (patch) | |
tree | 3814f79c10d7b490948d8cb7b112ac1dd41ceff1 /src/mongo/db/ops/modifier_bit.cpp | |
parent | 01965cf52bce6976637ecb8f4a622aeb05ab256a (diff) | |
download | mongo-9c2ed42daa8fbbef4a919c21ec564e2db55e8d60.tar.gz |
SERVER-18579: Clang-Format - reformat code, no comment reflow
Diffstat (limited to 'src/mongo/db/ops/modifier_bit.cpp')
-rw-r--r-- | src/mongo/db/ops/modifier_bit.cpp | 394 |
1 files changed, 182 insertions, 212 deletions
diff --git a/src/mongo/db/ops/modifier_bit.cpp b/src/mongo/db/ops/modifier_bit.cpp index c6d221875f9..bdddb9415f2 100644 --- a/src/mongo/db/ops/modifier_bit.cpp +++ b/src/mongo/db/ops/modifier_bit.cpp @@ -38,263 +38,233 @@ namespace mongo { - namespace mb = mutablebson; - namespace str = mongoutils::str; +namespace mb = mutablebson; +namespace str = mongoutils::str; - struct ModifierBit::PreparedState { +struct ModifierBit::PreparedState { + PreparedState(mutablebson::Document& doc) + : doc(doc), idxFound(0), elemFound(doc.end()), noOp(false) {} - PreparedState(mutablebson::Document& doc) - : doc(doc) - , idxFound(0) - , elemFound(doc.end()) - , noOp(false) { - } + // Document that is going to be changed. + mutablebson::Document& doc; + + // Index in _fieldRef for which an Element exist in the document. + size_t idxFound; - // Document that is going to be changed. - mutablebson::Document& doc; + // Element corresponding to _fieldRef[0.._idxFound]. + mutablebson::Element elemFound; - // Index in _fieldRef for which an Element exist in the document. - size_t idxFound; + // Value to be applied. + SafeNum newValue; - // Element corresponding to _fieldRef[0.._idxFound]. - mutablebson::Element elemFound; + // True if this update is a no-op + bool noOp; +}; - // Value to be applied. - SafeNum newValue; +ModifierBit::ModifierBit() : ModifierInterface(), _fieldRef(), _posDollar(0), _ops() {} - // True if this update is a no-op - bool noOp; - }; +ModifierBit::~ModifierBit() {} - ModifierBit::ModifierBit() - : ModifierInterface () - , _fieldRef() - , _posDollar(0) - , _ops() { +Status ModifierBit::init(const BSONElement& modExpr, const Options& opts, bool* positional) { + // Perform standard field name and updateable checks. + _fieldRef.parse(modExpr.fieldName()); + Status status = fieldchecker::isUpdatable(_fieldRef); + if (!status.isOK()) { + return status; } - ModifierBit::~ModifierBit() { + // If a $-positional operator was used, get the index in which it occurred + // and ensure only one occurrence. + size_t foundCount; + bool foundDollar = fieldchecker::isPositional(_fieldRef, &_posDollar, &foundCount); + + if (positional) + *positional = foundDollar; + + if (foundDollar && foundCount > 1) { + return Status(ErrorCodes::BadValue, + str::stream() << "Too many positional (i.e. '$') elements found in path '" + << _fieldRef.dottedField() << "'"); } - Status ModifierBit::init(const BSONElement& modExpr, const Options& opts, - bool* positional) { + if (modExpr.type() != mongo::Object) + return Status(ErrorCodes::BadValue, + str::stream() << "The $bit modifier is not compatible with a " + << typeName(modExpr.type()) + << ". You must pass in an embedded document: " + "{$bit: {field: {and/or/xor: #}}"); - // Perform standard field name and updateable checks. - _fieldRef.parse(modExpr.fieldName()); - Status status = fieldchecker::isUpdatable(_fieldRef); - if (! status.isOK()) { - return status; - } + BSONObjIterator opsIterator(modExpr.embeddedObject()); - // If a $-positional operator was used, get the index in which it occurred - // and ensure only one occurrence. - size_t foundCount; - bool foundDollar = fieldchecker::isPositional(_fieldRef, &_posDollar, &foundCount); + while (opsIterator.more()) { + BSONElement curOp = opsIterator.next(); - if (positional) - *positional = foundDollar; + const StringData payloadFieldName = curOp.fieldName(); - if (foundDollar && foundCount > 1) { - return Status(ErrorCodes::BadValue, - str::stream() << "Too many positional (i.e. '$') elements found in path '" - << _fieldRef.dottedField() << "'"); - } + SafeNumOp op = NULL; - if (modExpr.type() != mongo::Object) + if (payloadFieldName == "and") { + op = &SafeNum::bitAnd; + } else if (payloadFieldName == "or") { + op = &SafeNum::bitOr; + } else if (payloadFieldName == "xor") { + op = &SafeNum::bitXor; + } else { return Status(ErrorCodes::BadValue, - str::stream() << "The $bit modifier is not compatible with a " - << typeName(modExpr.type()) - << ". You must pass in an embedded document: " - "{$bit: {field: {and/or/xor: #}}"); - - BSONObjIterator opsIterator(modExpr.embeddedObject()); - - while (opsIterator.more()) { - BSONElement curOp = opsIterator.next(); - - const StringData payloadFieldName = curOp.fieldName(); - - SafeNumOp op = NULL; - - if (payloadFieldName == "and") { - op = &SafeNum::bitAnd; - } - else if (payloadFieldName == "or") { - op = &SafeNum::bitOr; - } - else if (payloadFieldName == "xor") { - op = &SafeNum::bitXor; - } - else { - return Status( - ErrorCodes::BadValue, - str::stream() << "The $bit modifier only supports 'and', 'or', and 'xor', not '" - << payloadFieldName - << "' which is an unknown operator: {" << curOp << "}"); - } - - if ((curOp.type() != mongo::NumberInt) && - (curOp.type() != mongo::NumberLong)) - return Status( - ErrorCodes::BadValue, - str::stream() << "The $bit modifier field must be an Integer(32/64 bit); a '" - << typeName(curOp.type()) - << "' is not supported here: {" << curOp << "}"); - - const OpEntry entry = {SafeNum(curOp), op}; - _ops.push_back(entry); + str::stream() + << "The $bit modifier only supports 'and', 'or', and 'xor', not '" + << payloadFieldName << "' which is an unknown operator: {" << curOp + << "}"); } - dassert(!_ops.empty()); + if ((curOp.type() != mongo::NumberInt) && (curOp.type() != mongo::NumberLong)) + return Status(ErrorCodes::BadValue, + str::stream() + << "The $bit modifier field must be an Integer(32/64 bit); a '" + << typeName(curOp.type()) << "' is not supported here: {" << curOp + << "}"); - return Status::OK(); + const OpEntry entry = {SafeNum(curOp), op}; + _ops.push_back(entry); } - Status ModifierBit::prepare(mutablebson::Element root, - StringData matchedField, - ExecInfo* execInfo) { - - _preparedState.reset(new PreparedState(root.getDocument())); - - // If we have a $-positional field, it is time to bind it to an actual field part. - if (_posDollar) { - if (matchedField.empty()) { - return Status(ErrorCodes::BadValue, - str::stream() << "The positional operator did not find the match " - "needed from the query. Unexpanded update: " - << _fieldRef.dottedField()); - } - _fieldRef.setPart(_posDollar, matchedField); - } + dassert(!_ops.empty()); - // Locate the field name in 'root'. - Status status = pathsupport::findLongestPrefix(_fieldRef, - root, - &_preparedState->idxFound, - &_preparedState->elemFound); + return Status::OK(); +} +Status ModifierBit::prepare(mutablebson::Element root, + StringData matchedField, + ExecInfo* execInfo) { + _preparedState.reset(new PreparedState(root.getDocument())); - // FindLongestPrefix may say the path does not exist at all, which is fine here, or - // that the path was not viable or otherwise wrong, in which case, the mod cannot - // proceed. - if (status.code() == ErrorCodes::NonExistentPath) { - _preparedState->elemFound = root.getDocument().end(); - } - else if (!status.isOK()) { - return status; + // If we have a $-positional field, it is time to bind it to an actual field part. + if (_posDollar) { + if (matchedField.empty()) { + return Status(ErrorCodes::BadValue, + str::stream() << "The positional operator did not find the match " + "needed from the query. Unexpanded update: " + << _fieldRef.dottedField()); } + _fieldRef.setPart(_posDollar, matchedField); + } - // We register interest in the field name. The driver needs this info to sort out if - // there is any conflict among mods. - execInfo->fieldRef[0] = &_fieldRef; - - // - // in-place and no-op logic - // - - // If the field path is not fully present, then this mod cannot be in place, nor is a - // noOp. - if (!_preparedState->elemFound.ok() || - _preparedState->idxFound < (_fieldRef.numParts() - 1)) { - // If no target element exists, the value we will write is the result of applying - // the operation to a zero-initialized integer element. - _preparedState->newValue = apply(SafeNum(static_cast<int>(0))); - return Status::OK(); - } + // Locate the field name in 'root'. + Status status = pathsupport::findLongestPrefix( + _fieldRef, root, &_preparedState->idxFound, &_preparedState->elemFound); - if (!_preparedState->elemFound.isIntegral()) { - mb::Element idElem = mb::findElementNamed(root.leftChild(), "_id"); - return Status( - ErrorCodes::BadValue, - str::stream() << "Cannot apply $bit to a value of non-integral type." - << idElem.toString() - << " has the field " << _preparedState->elemFound.getFieldName() - << " of non-integer type " - << typeName(_preparedState->elemFound.getType())); - } - const SafeNum currentValue = _preparedState->elemFound.getValueSafeNum(); + // FindLongestPrefix may say the path does not exist at all, which is fine here, or + // that the path was not viable or otherwise wrong, in which case, the mod cannot + // proceed. + if (status.code() == ErrorCodes::NonExistentPath) { + _preparedState->elemFound = root.getDocument().end(); + } else if (!status.isOK()) { + return status; + } - // Apply the op over the existing value and the mod value, and capture the result. - _preparedState->newValue = apply(currentValue); + // We register interest in the field name. The driver needs this info to sort out if + // there is any conflict among mods. + execInfo->fieldRef[0] = &_fieldRef; - if (!_preparedState->newValue.isValid()) { - // TODO: Include list of ops, if that is easy, at some future point. - return Status(ErrorCodes::BadValue, - str::stream() << "Failed to apply $bit operations to current value: " - << currentValue.debugString()); - } - // If the values are identical (same type, same value), then this is a no-op. - if (_preparedState->newValue.isIdentical(currentValue)) { - _preparedState->noOp = execInfo->noOp = true; - return Status::OK(); - } + // + // in-place and no-op logic + // + // If the field path is not fully present, then this mod cannot be in place, nor is a + // noOp. + if (!_preparedState->elemFound.ok() || _preparedState->idxFound < (_fieldRef.numParts() - 1)) { + // If no target element exists, the value we will write is the result of applying + // the operation to a zero-initialized integer element. + _preparedState->newValue = apply(SafeNum(static_cast<int>(0))); return Status::OK(); } - Status ModifierBit::apply() const { - dassert(_preparedState->noOp == false); - - // If there's no need to create any further field part, the $bit is simply a value - // assignment. - if (_preparedState->elemFound.ok() && - _preparedState->idxFound == (_fieldRef.numParts() - 1)) { - return _preparedState->elemFound.setValueSafeNum(_preparedState->newValue); - } - - // - // Complete document path logic - // + if (!_preparedState->elemFound.isIntegral()) { + mb::Element idElem = mb::findElementNamed(root.leftChild(), "_id"); + return Status(ErrorCodes::BadValue, + str::stream() << "Cannot apply $bit to a value of non-integral type." + << idElem.toString() << " has the field " + << _preparedState->elemFound.getFieldName() + << " of non-integer type " + << typeName(_preparedState->elemFound.getType())); + } - // Creates the final element that's going to be $set in 'doc'. - mutablebson::Document& doc = _preparedState->doc; - StringData lastPart = _fieldRef.getPart(_fieldRef.numParts() - 1); - mutablebson::Element elemToSet = doc.makeElementSafeNum(lastPart, _preparedState->newValue); - if (!elemToSet.ok()) { - return Status(ErrorCodes::InternalError, "can't create new element"); - } + const SafeNum currentValue = _preparedState->elemFound.getValueSafeNum(); - // Now, we can be in two cases here, as far as attaching the element being set goes: - // (a) none of the parts in the element's path exist, or (b) some parts of the path - // exist but not all. - if (!_preparedState->elemFound.ok()) { - _preparedState->elemFound = doc.root(); - _preparedState->idxFound = 0; - } - else { - _preparedState->idxFound++; - } + // Apply the op over the existing value and the mod value, and capture the result. + _preparedState->newValue = apply(currentValue); - // createPathAt() will complete the path and attach 'elemToSet' at the end of it. - return pathsupport::createPathAt(_fieldRef, - _preparedState->idxFound, - _preparedState->elemFound, - elemToSet); + if (!_preparedState->newValue.isValid()) { + // TODO: Include list of ops, if that is easy, at some future point. + return Status(ErrorCodes::BadValue, + str::stream() << "Failed to apply $bit operations to current value: " + << currentValue.debugString()); + } + // If the values are identical (same type, same value), then this is a no-op. + if (_preparedState->newValue.isIdentical(currentValue)) { + _preparedState->noOp = execInfo->noOp = true; + return Status::OK(); } - Status ModifierBit::log(LogBuilder* logBuilder) const { + return Status::OK(); +} - mutablebson::Element logElement = logBuilder->getDocument().makeElementSafeNum( - _fieldRef.dottedField(), - _preparedState->newValue); +Status ModifierBit::apply() const { + dassert(_preparedState->noOp == false); - if (!logElement.ok()) { - return Status(ErrorCodes::InternalError, - str::stream() << "Could not append entry to $bit oplog entry: " - << "set '" << _fieldRef.dottedField() << "' -> " - << _preparedState->newValue.debugString() ); - } - return logBuilder->addToSets(logElement); + // If there's no need to create any further field part, the $bit is simply a value + // assignment. + if (_preparedState->elemFound.ok() && _preparedState->idxFound == (_fieldRef.numParts() - 1)) { + return _preparedState->elemFound.setValueSafeNum(_preparedState->newValue); + } + // + // Complete document path logic + // + + // Creates the final element that's going to be $set in 'doc'. + mutablebson::Document& doc = _preparedState->doc; + StringData lastPart = _fieldRef.getPart(_fieldRef.numParts() - 1); + mutablebson::Element elemToSet = doc.makeElementSafeNum(lastPart, _preparedState->newValue); + if (!elemToSet.ok()) { + return Status(ErrorCodes::InternalError, "can't create new element"); } - SafeNum ModifierBit::apply(SafeNum value) const { - OpEntries::const_iterator where = _ops.begin(); - const OpEntries::const_iterator end = _ops.end(); - for (; where != end; ++where) - value = (value.*(where->op))(where->val); - return value; + // Now, we can be in two cases here, as far as attaching the element being set goes: + // (a) none of the parts in the element's path exist, or (b) some parts of the path + // exist but not all. + if (!_preparedState->elemFound.ok()) { + _preparedState->elemFound = doc.root(); + _preparedState->idxFound = 0; + } else { + _preparedState->idxFound++; } -} // namespace mongo + // createPathAt() will complete the path and attach 'elemToSet' at the end of it. + return pathsupport::createPathAt( + _fieldRef, _preparedState->idxFound, _preparedState->elemFound, elemToSet); +} + +Status ModifierBit::log(LogBuilder* logBuilder) const { + mutablebson::Element logElement = logBuilder->getDocument().makeElementSafeNum( + _fieldRef.dottedField(), _preparedState->newValue); + + if (!logElement.ok()) { + return Status(ErrorCodes::InternalError, + str::stream() << "Could not append entry to $bit oplog entry: " + << "set '" << _fieldRef.dottedField() << "' -> " + << _preparedState->newValue.debugString()); + } + return logBuilder->addToSets(logElement); +} + +SafeNum ModifierBit::apply(SafeNum value) const { + OpEntries::const_iterator where = _ops.begin(); + const OpEntries::const_iterator end = _ops.end(); + for (; where != end; ++where) + value = (value.*(where->op))(where->val); + return value; +} + +} // namespace mongo |