@@ -2077,10 +2077,9 @@ ENGINE_ERROR_CODE VBucket::deleteItem(
20772077 ENGINE_ERROR_CODE ret = durability ? ENGINE_EWOULDBLOCK : ENGINE_SUCCESS;
20782078
20792079 { // HashBucketLock scope
2080- auto htRes = durability ? ht.findForSyncWrite (cHandle.getKey ())
2081- : ht.findForWrite (cHandle.getKey ());
2082- auto * v = htRes.storedValue ;
2083- auto & hbl = htRes.lock ;
2080+ auto htRes = ht.findForCommit (cHandle.getKey ());
2081+ auto * v = htRes.selectSVToModify (durability.is_initialized ());
2082+ auto & hbl = htRes.getHBL ();
20842083
20852084 if (!v || v->isDeleted () || v->isTempItem () ||
20862085 cHandle.isLogicallyDeleted (v->getBySeqno ())) {
@@ -2135,7 +2134,7 @@ ENGINE_ERROR_CODE VBucket::deleteItem(
21352134 queueItmCtx.durability = DurabilityItemCtx{*durability, cookie};
21362135 }
21372136 std::tie (delrv, v, notifyCtx) =
2138- processSoftDelete (hbl ,
2137+ processSoftDelete (htRes ,
21392138 *v,
21402139 cas,
21412140 metadata,
@@ -2215,9 +2214,9 @@ ENGINE_ERROR_CODE VBucket::deleteWithMeta(
22152214 const Collections::VB::Manifest::CachingReadHandle& cHandle,
22162215 DeleteSource deleteSource) {
22172216 const auto & key = cHandle.getKey ();
2218- auto htRes = ht.findForWrite (key);
2219- auto * v = htRes.storedValue ;
2220- auto & hbl = htRes.lock ;
2217+ auto htRes = ht.findForCommit (key);
2218+ auto * v = htRes.pending ? htRes. pending . getSV () : htRes. committed ;
2219+ auto & hbl = htRes.pending . getHBL () ;
22212220
22222221 if (v && cHandle.isLogicallyDeleted (v->getBySeqno ())) {
22232222 return ENGINE_KEY_ENOENT;
@@ -2317,7 +2316,7 @@ ENGINE_ERROR_CODE VBucket::deleteWithMeta(
23172316 // this is a replication call (i.e. not to an active vbucket),
23182317 // the active has done this and we must just store what we're
23192318 // given.
2320- std::tie (delrv, v, notifyCtx) = processSoftDelete (hbl ,
2319+ std::tie (delrv, v, notifyCtx) = processSoftDelete (htRes ,
23212320 *v,
23222321 cas,
23232322 itemMeta,
@@ -3376,15 +3375,14 @@ std::pair<AddStatus, boost::optional<VBNotifyCtx>> VBucket::processAdd(
33763375}
33773376
33783377std::tuple<MutationStatus, StoredValue*, boost::optional<VBNotifyCtx>>
3379- VBucket::processSoftDelete (const HashTable::HashBucketLock& hbl ,
3378+ VBucket::processSoftDelete (HashTable::FindCommitResult& htRes ,
33803379 StoredValue& v,
33813380 uint64_t cas,
33823381 const ItemMetaData& metadata,
33833382 const VBQueueItemCtx& queueItmCtx,
33843383 bool use_meta,
33853384 uint64_t bySeqno,
33863385 DeleteSource deleteSource) {
3387- boost::optional<VBNotifyCtx> empty;
33883386 if (v.isPending ()) {
33893387 // It is not valid for an active vBucket to attempt to overwrite an
33903388 // in flight SyncWrite. If this vBucket is not active, we are
@@ -3395,14 +3393,40 @@ VBucket::processSoftDelete(const HashTable::HashBucketLock& hbl,
33953393 // missing a prepare. This code allows this mutation to be accepted
33963394 // and overwrites the existing prepare.
33973395 if (getState () == vbucket_state_active || !isReceivingDiskSnapshot ()) {
3398- return {MutationStatus::IsPendingSyncWrite, &v, empty };
3396+ return {MutationStatus::IsPendingSyncWrite, &v, boost::none };
33993397 }
34003398
34013399 getPassiveDM ().completeSyncWrite (
34023400 StoredDocKey (v.getKey ()),
34033401 PassiveDurabilityMonitor::Resolution::Commit);
3402+
3403+ // @TODO we must remove the prepare and overwrite the mutation if we
3404+ // are replacing a prepare with a mutation
3405+ // Release the pending SV from the SVP that is holding it to prevent
3406+ // a double stat update that would cause a stat underflow exception.
3407+ htRes.pending .release ();
34043408 }
34053409
3410+ return processSoftDeleteInner (htRes.getHBL (),
3411+ v,
3412+ cas,
3413+ metadata,
3414+ queueItmCtx,
3415+ use_meta,
3416+ bySeqno,
3417+ deleteSource);
3418+ }
3419+
3420+ std::tuple<MutationStatus, StoredValue*, boost::optional<VBNotifyCtx>>
3421+ VBucket::processSoftDeleteInner (const HashTable::HashBucketLock& hbl,
3422+ StoredValue& v,
3423+ uint64_t cas,
3424+ const ItemMetaData& metadata,
3425+ const VBQueueItemCtx& queueItmCtx,
3426+ bool use_meta,
3427+ uint64_t bySeqno,
3428+ DeleteSource deleteSource) {
3429+ boost::optional<VBNotifyCtx> empty;
34063430 if (v.isTempInitialItem () && eviction == EvictionPolicy::Full) {
34073431 return std::make_tuple (MutationStatus::NeedBgFetch, &v, empty);
34083432 }
0 commit comments