@@ -2625,74 +2625,44 @@ bool CacheAllocator<CacheTrait>::moveForSlabRelease(
26252625 Item *parentItem;
26262626 bool chainedItem = oldItem.isChainedItem ();
26272627
2628- for (unsigned int itemMovingAttempts = 0 ;
2629- itemMovingAttempts < config_.movingTries ;
2630- ++itemMovingAttempts) {
2631- stats_.numMoveAttempts .inc ();
2632-
2633- // Nothing to move - in the case that tryMoving failed
2634- // for chained items we would have already evicted the entire chain.
2635- if (oldItem.isOnlyMoving ()) {
2636- XDCHECK (!oldItem.isChainedItem ());
2637- auto ret = unmarkMovingAndWakeUpWaiters (oldItem, {});
2638- XDCHECK (ret == 0 );
2639- const auto res =
2640- releaseBackToAllocator (oldItem, RemoveContext::kNormal , false );
2641- XDCHECK (res == ReleaseRes::kReleased );
2642- return true ;
2643- }
2644-
2645- if (!newItemHdl) {
2646- // try to allocate again if it previously wasn't successful
2647- if (chainedItem) {
2648- parentItem = &oldItem.asChainedItem ().getParentItem (compressor_);
2649- XDCHECK (parentItem->isMoving ());
2650- XDCHECK (oldItem.isChainedItem () && oldItem.getRefCount () == 1 );
2651- XDCHECK_EQ (0 , parentItem->getRefCount ());
2652- newItemHdl =
2653- allocateChainedItemInternal (*parentItem, oldItem.getSize ());
2654- } else {
2655- XDCHECK (oldItem.isMoving ());
2656- newItemHdl = allocateNewItemForOldItem (oldItem);
2657- }
2658- }
2628+ stats_.numMoveAttempts .inc ();
2629+
2630+ // Nothing to move - in the case that tryMoving failed
2631+ // for chained items we would have already evicted the entire chain.
2632+ if (oldItem.isOnlyMoving ()) {
2633+ XDCHECK (!oldItem.isChainedItem ());
2634+ auto ret = unmarkMovingAndWakeUpWaiters (oldItem, {});
2635+ XDCHECK (ret == 0 );
2636+ const auto res =
2637+ releaseBackToAllocator (oldItem, RemoveContext::kNormal , false );
2638+ XDCHECK (res == ReleaseRes::kReleased );
2639+ return true ;
2640+ }
26592641
2660- // if we have a valid handle, try to move, if not, we retry.
2661- if (newItemHdl) {
2662- isMoved = tryMovingForSlabRelease (oldItem, newItemHdl);
2663- if (isMoved) {
2664- break ;
2665- }
2666- }
2642+ // try to allocate again if it previously wasn't successful
2643+ if (chainedItem) {
2644+ parentItem = &oldItem.asChainedItem ().getParentItem (compressor_);
2645+ XDCHECK (parentItem->isMoving ());
2646+ XDCHECK (oldItem.isChainedItem () && oldItem.getRefCount () == 1 );
2647+ XDCHECK_EQ (0 , parentItem->getRefCount ());
2648+ newItemHdl =
2649+ allocateChainedItemInternal (*parentItem, oldItem.getSize ());
2650+ } else {
2651+ XDCHECK (oldItem.isMoving ());
2652+ newItemHdl = allocateNewItemForOldItem (oldItem);
2653+ }
2654+
26672655
2668- throttleWith (throttler, [&] {
2669- XLOGF (WARN,
2670- " Spent {} seconds, slab release still trying to move Item: {}. "
2671- " Pool: {}, Class: {}." ,
2672- util::getCurrentTimeSec () - startTime, oldItem.toString (),
2673- ctx.getPoolId (), ctx.getClassId ());
2674- });
2656+ // if we have a valid handle, try to move, if not, we retry.
2657+ if (newItemHdl) {
2658+ isMoved = tryMovingForSlabRelease (oldItem, newItemHdl);
26752659 }
26762660
26772661 // Return false if we've exhausted moving tries.
26782662 if (!isMoved) {
26792663 return false ;
26802664 }
26812665
2682- // Since item has been moved, we can directly free it. We don't need to
2683- // worry about any stats related changes, because there is another item
2684- // that's identical to this one to replace it. Here we just need to wait
2685- // until all users have dropped the item handles before we can proceed.
2686- startTime = util::getCurrentTimeSec ();
2687- while (!chainedItem && !oldItem.isOnlyMoving ()) {
2688- throttleWith (throttler, [&] {
2689- XLOGF (WARN,
2690- " Spent {} seconds, slab release still waiting for refcount to "
2691- " drain Item: {}. Pool: {}, Class: {}." ,
2692- util::getCurrentTimeSec () - startTime, oldItem.toString (),
2693- ctx.getPoolId (), ctx.getClassId ());
2694- });
2695- }
26962666 const auto allocInfo = allocator_->getAllocInfo (oldItem.getMemory ());
26972667 if (chainedItem) {
26982668 newItemHdl.reset ();
@@ -2800,30 +2770,6 @@ CacheAllocator<CacheTrait>::allocateNewItemForOldItem(const Item& oldItem) {
28002770template <typename CacheTrait>
28012771bool CacheAllocator<CacheTrait>::tryMovingForSlabRelease(
28022772 Item& oldItem, WriteHandle& newItemHdl) {
2803- // By holding onto a user-level synchronization object, we ensure moving
2804- // a regular item or chained item is synchronized with any potential
2805- // user-side mutation.
2806- std::unique_ptr<SyncObj> syncObj;
2807- if (config_.movingSync ) {
2808- if (!oldItem.isChainedItem ()) {
2809- syncObj = config_.movingSync (oldItem.getKey ());
2810- } else {
2811- // Copy the key so we have a valid key to work with if the chained
2812- // item is still valid.
2813- const std::string parentKey =
2814- oldItem.asChainedItem ().getParentItem (compressor_).getKey ().str ();
2815- syncObj = config_.movingSync (parentKey);
2816- }
2817-
2818- // We need to differentiate between the following three scenarios:
2819- // 1. nullptr indicates no move sync required for this particular item
2820- // 2. moveSync.isValid() == true meaning we've obtained the sync
2821- // 3. moveSync.isValid() == false meaning we need to abort and retry
2822- if (syncObj && !syncObj->isValid ()) {
2823- return false ;
2824- }
2825- }
2826-
28272773 // move can fail if another thread calls insertOrReplace
28282774 // in this case oldItem is no longer valid (not accessible,
28292775 // it gets removed from MMContainer and evictForSlabRelease
0 commit comments