@@ -424,7 +424,8 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
424424 uint32_t size,
425425 uint32_t creationTime,
426426 uint32_t expiryTime,
427- bool fromBgThread) {
427+ bool fromBgThread,
428+ bool evict) {
428429 util::LatencyTracker tracker{stats ().allocateLatency_ };
429430
430431 SCOPE_FAIL { stats_.invalidAllocs .inc (); };
@@ -445,7 +446,9 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
445446 backgroundEvictor_[backgroundWorkerId (tid, pid, cid, backgroundEvictor_.size ())]->wakeUp ();
446447 }
447448
448- if (memory == nullptr ) {
449+ if (memory == nullptr && !evict) {
450+ return {};
451+ } else if (memory == nullptr ) {
449452 memory = findEviction (tid, pid, cid);
450453 }
451454
@@ -495,7 +498,8 @@ CacheAllocator<CacheTrait>::allocateInternal(PoolId pid,
495498 bool fromBgThread) {
496499 auto tid = 0 ; /* TODO: consult admission policy */
497500 for (TierId tid = 0 ; tid < getNumTiers (); ++tid) {
498- auto handle = allocateInternalTier (tid, pid, key, size, creationTime, expiryTime, fromBgThread);
501+ bool evict = !config_.insertToFirstFreeTier || tid == getNumTiers () - 1 ;
502+ auto handle = allocateInternalTier (tid, pid, key, size, creationTime, expiryTime, fromBgThread, evict);
499503 if (handle) return handle;
500504 }
501505 return {};
@@ -1829,13 +1833,17 @@ CacheAllocator<CacheTrait>::tryEvictToNextMemoryTier(
18291833
18301834 TierId nextTier = tid; // TODO - calculate this based on some admission policy
18311835 while (++nextTier < getNumTiers ()) { // try to evict down to the next memory tiers
1836+ // always evict item from the nextTier to make room for new item
1837+ bool evict = true ;
1838+
18321839 // allocateInternal might trigger another eviction
18331840 auto newItemHdl = allocateInternalTier (nextTier, pid,
18341841 item.getKey (),
18351842 item.getSize (),
18361843 item.getCreationTime (),
18371844 item.getExpiryTime (),
1838- fromBgThread);
1845+ fromBgThread,
1846+ evict);
18391847
18401848 if (newItemHdl) {
18411849 XDCHECK_EQ (newItemHdl->getSize (), item.getSize ());
@@ -1871,13 +1879,17 @@ CacheAllocator<CacheTrait>::tryPromoteToNextMemoryTier(
18711879 auto toPromoteTier = nextTier - 1 ;
18721880 --nextTier;
18731881
1882+ // always evict item from the toPromoteTier to make room for new item
1883+ bool evict = true ;
1884+
18741885 // allocateInternal might trigger another eviction
18751886 auto newItemHdl = allocateInternalTier (toPromoteTier, pid,
18761887 item.getKey (),
18771888 item.getSize (),
18781889 item.getCreationTime (),
18791890 item.getExpiryTime (),
1880- fromBgThread);
1891+ fromBgThread,
1892+ true );
18811893
18821894 if (newItemHdl) {
18831895 XDCHECK_EQ (newItemHdl->getSize (), item.getSize ());
@@ -3251,6 +3263,8 @@ CacheAllocator<CacheTrait>::allocateNewItemForOldItem(const Item& oldItem) {
32513263
32523264 const auto allocInfo =
32533265 allocator_[getTierId (oldItem)]->getAllocInfo (static_cast <const void *>(&oldItem));
3266+
3267+ bool evict = !config_.insertToFirstFreeTier || getTierId (oldItem) == getNumTiers () - 1 ;
32543268
32553269 // Set up the destination for the move. Since oldItem would have the moving
32563270 // bit set, it won't be picked for eviction.
@@ -3260,7 +3274,8 @@ CacheAllocator<CacheTrait>::allocateNewItemForOldItem(const Item& oldItem) {
32603274 oldItem.getSize (),
32613275 oldItem.getCreationTime (),
32623276 oldItem.getExpiryTime (),
3263- false );
3277+ false ,
3278+ evict);
32643279 if (!newItemHdl) {
32653280 return {};
32663281 }
0 commit comments