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(); }
// Remove the provided doc from the index. Status AbstractIndexAccessMethod::remove(OperationContext* opCtx, const BSONObj& obj, const RecordId& loc, const InsertDeleteOptions& options, int64_t* numDeleted) { invariant(!_btreeState->isBuilding()); invariant(numDeleted); *numDeleted = 0; BSONObjSet keys = SimpleBSONObjComparator::kInstance.makeBSONObjSet(); // There's no need to compute the prefixes of the indexed fields that cause the index to be // multikey when removing a document since the index metadata isn't updated when keys are // deleted. BSONObjSet* multikeyMetadataKeys = nullptr; MultikeyPaths* multikeyPaths = nullptr; // Relax key constraints on removal when deleting documents with invalid formats, but only // those that don't apply to the partialIndex filter. getKeys( obj, GetKeysMode::kRelaxConstraintsUnfiltered, &keys, multikeyMetadataKeys, multikeyPaths); return removeKeys(opCtx, keys, loc, options, numDeleted); }