Skip to content

Commit 5632d18

Browse files
igchorbyrnedj
authored andcommitted
Add option to insert items to first free tier (#87)
instead of always inserting to topmost tier
1 parent 50d3ae5 commit 5632d18

File tree

6 files changed

+49
-7
lines changed

6 files changed

+49
-7
lines changed

cachelib/allocator/CacheAllocator-inl.h

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

cachelib/allocator/CacheAllocator.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1521,13 +1521,19 @@ class CacheAllocator : public CacheBase {
15211521
// For description see allocateInternal.
15221522
//
15231523
// @param tid id a memory tier
1524+
// @param fromBgThread whether this function was called from a bg
1525+
// thread - this is used to decide whether bg thread should
1526+
// be waken in case there is no free memory
1527+
// @param evict whether to evict an item from tier tid in case there
1528+
// is not enough memory
15241529
WriteHandle allocateInternalTier(TierId tid,
15251530
PoolId id,
15261531
Key key,
15271532
uint32_t size,
15281533
uint32_t creationTime,
15291534
uint32_t expiryTime,
1530-
bool fromBgThread);
1535+
bool fromBgThread,
1536+
bool evict);
15311537

15321538
// Allocate a chained item
15331539
//

cachelib/allocator/CacheAllocatorConfig.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ class CacheAllocatorConfig {
311311
// Library team if you find yourself customizing this.
312312
CacheAllocatorConfig& setThrottlerConfig(util::Throttler::Config config);
313313

314+
// Insert items to first free memory tier
315+
CacheAllocatorConfig& enableInsertToFirstFreeTier();
316+
314317
// Passes in a callback to initialize an event tracker when the allocator
315318
// starts
316319
CacheAllocatorConfig& setEventTracker(EventTrackerSharedPtr&&);
@@ -527,6 +530,11 @@ class CacheAllocatorConfig {
527530
// ABOVE are the config for various cache workers
528531
//
529532

533+
// if turned off, always insert new elements to topmost memory tier.
534+
// if turned on, insert new element to first free memory tier or evict memory
535+
// from the bottom one if memory cache is full
536+
bool insertToFirstFreeTier = false;
537+
530538
// the number of tries to search for an item to evict
531539
// 0 means it's infinite
532540
unsigned int evictionSearchTries{50};
@@ -662,6 +670,12 @@ class CacheAllocatorConfig {
662670
{MemoryTierCacheConfig::fromShm().setRatio(1)}};
663671
};
664672

673+
template <typename T>
674+
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableInsertToFirstFreeTier() {
675+
insertToFirstFreeTier = true;
676+
return *this;
677+
}
678+
665679
template <typename T>
666680
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheName(
667681
const std::string& _cacheName) {
@@ -1241,6 +1255,7 @@ std::map<std::string, std::string> CacheAllocatorConfig<T>::serialize() const {
12411255
configMap["nvmAdmissionMinTTL"] = std::to_string(nvmAdmissionMinTTL);
12421256
configMap["delayCacheWorkersStart"] =
12431257
delayCacheWorkersStart ? "true" : "false";
1258+
configMap["insertToFirstFreeTier"] = std::to_string(insertToFirstFreeTier);
12441259
mergeWithPrefix(configMap, throttleConfig.serialize(), "throttleConfig");
12451260
mergeWithPrefix(configMap,
12461261
chainedItemAccessConfig.serialize(),

cachelib/cachebench/cache/Cache-inl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ Cache<Allocator>::Cache(const CacheConfig& config,
104104
allocatorConfig_.configureMemoryTiers(config_.memoryTierConfigs);
105105
}
106106

107+
allocatorConfig_.insertToFirstFreeTier = config_.insertToFirstFreeTier;
108+
107109
auto cleanupGuard = folly::makeGuard([&] {
108110
if (!nvmCacheFilePath_.empty()) {
109111
util::removePath(nvmCacheFilePath_);

cachelib/cachebench/util/CacheConfig.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ CacheConfig::CacheConfig(const folly::dynamic& configJson) {
4949
JSONSetVal(configJson, tryLockUpdate);
5050
JSONSetVal(configJson, lruIpSpec);
5151
JSONSetVal(configJson, useCombinedLockForIterators);
52+
53+
JSONSetVal(configJson, insertToFirstFreeTier);
5254

5355
JSONSetVal(configJson, lru2qHotPct);
5456
JSONSetVal(configJson, lru2qColdPct);

cachelib/cachebench/util/CacheConfig.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ struct CacheConfig : public JSONConfig {
9797
bool lruUpdateOnRead{true};
9898
bool tryLockUpdate{false};
9999
bool useCombinedLockForIterators{true};
100+
101+
bool insertToFirstFreeTier{false};
100102

101103
// LRU param
102104
uint64_t lruIpSpec{0};

0 commit comments

Comments
 (0)