예제 #1
0
Status IndexBuildInterceptor::_applyWrite(OperationContext* opCtx,
                                          const BSONObj& operation,
                                          const InsertDeleteOptions& options,
                                          int64_t* const keysInserted,
                                          int64_t* const keysDeleted) {
    const BSONObj key = operation["key"].Obj();
    const RecordId opRecordId = RecordId(operation["recordId"].Long());
    const Op opType =
        (strcmp(operation.getStringField("op"), "i") == 0) ? Op::kInsert : Op::kDelete;
    const BSONObjSet keySet = SimpleBSONObjComparator::kInstance.makeBSONObjSet({key});

    auto accessMethod = _indexCatalogEntry->accessMethod();
    if (opType == Op::kInsert) {
        InsertResult result;
        auto status = accessMethod->insertKeys(opCtx,
                                               keySet,
                                               SimpleBSONObjComparator::kInstance.makeBSONObjSet(),
                                               MultikeyPaths{},
                                               opRecordId,
                                               options,
                                               &result);
        if (!status.isOK()) {
            return status;
        }

        if (result.dupsInserted.size() &&
            options.getKeysMode == IndexAccessMethod::GetKeysMode::kEnforceConstraints) {
            status = recordDuplicateKeys(opCtx, result.dupsInserted);
            if (!status.isOK()) {
                return status;
            }
        }

        int64_t numInserted = result.numInserted;
        *keysInserted += numInserted;
        opCtx->recoveryUnit()->onRollback(
            [keysInserted, numInserted] { *keysInserted -= numInserted; });
    } else {
        invariant(opType == Op::kDelete);
        DEV invariant(strcmp(operation.getStringField("op"), "d") == 0);

        int64_t numDeleted;
        Status s = accessMethod->removeKeys(opCtx, keySet, opRecordId, options, &numDeleted);
        if (!s.isOK()) {
            return s;
        }

        *keysDeleted += numDeleted;
        opCtx->recoveryUnit()->onRollback(
            [keysDeleted, numDeleted] { *keysDeleted -= numDeleted; });
    }
    return Status::OK();
}
예제 #2
0
MojErr MojDbIndex::update(const MojObject* newObj, const MojObject* oldObj, MojDbStorageTxn* txn, bool forcedel)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(isOpen());
	MojAssert(newObj || oldObj);

	// figure out which versions we include
	bool includeOld = includeObj(oldObj);
	bool includeNew = includeObj(newObj);

	if (includeNew && !includeOld) {
		// we include the new but not the old, so just put all the new keys
		MojAssert(newObj);
		KeySet newKeys;
		MojErr err = getKeys(*newObj, newKeys);
		MojErrCheck(err);
		err = insertKeys(newKeys, txn);
		MojErrCheck(err);
		err = notifyWatches(newKeys, txn);
		MojErrCheck(err);
        LOG_DEBUG("[db_mojodb] IndexAdd: %s; Keys= %zu \n", this->m_name.data(), newKeys.size());
	} else if (includeOld && !includeNew) {
		// we include the old but not the new objects, so del all the old keys
		MojAssert(oldObj);
		KeySet oldKeys;
		MojErr err = getKeys(*oldObj, oldKeys);
		MojErrCheck(err);
		err = delKeys(oldKeys, txn, forcedel);
		MojErrCheck(err);
		err = notifyWatches(oldKeys, txn);
		MojErrCheck(err);
        LOG_DEBUG("[db_mojodb] IndexDel: %s; Keys= %zu \n", this->name().data(), oldKeys.size());
	} else if (includeNew && includeOld) {
		// we include old and new objects
		MojAssert(newObj && oldObj);
		KeySet newKeys;
		MojErr err = getKeys(*newObj, newKeys);
		MojErrCheck(err);
		KeySet oldKeys;
		err = getKeys(*oldObj, oldKeys);
		MojErrCheck(err);
		// we need to put the keys that are in the new set, but not in the old
		KeySet keysToPut;
		err = newKeys.diff(oldKeys, keysToPut);
		MojErrCheck(err);
		// we need to del the keys that are in the old set, but not in the new
		KeySet keysToDel;
		err = oldKeys.diff(newKeys, keysToDel);
		MojErrCheck(err);
		err = insertKeys(keysToPut, txn);
		MojErrCheck(err);
		err = delKeys(keysToDel, txn, forcedel);
		
        LOG_DEBUG("[db_mojodb] IndexMerge: %s; OldKeys= %zu; NewKeys= %zu; Dropped= %zu; Added= %zu ; err = %d\n",
			this->name().data(), oldKeys.size(), newKeys.size(), keysToDel.size(), keysToPut.size(), (int)err);

		MojErrCheck(err);
		// notify on union of old and new keys
		err = newKeys.put(oldKeys);
		MojErrCheck(err);
		err = notifyWatches(newKeys, txn);
		MojErrCheck(err);
	
	}
	return MojErrNone;
}