Skip to content

Commit 7d06531

Browse files
igchorbyrnedj
authored andcommitted
Add option to insert items to first free tier (#87)
instead of always inserting to topmost tier
1 parent 46d168c commit 7d06531

File tree

5 files changed

+47
-6
lines changed

5 files changed

+47
-6
lines changed

cachelib/allocator/CacheAllocator.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,13 +1528,19 @@ class CacheAllocator : public CacheBase {
15281528
// For description see allocateInternal.
15291529
//
15301530
// @param tid id a memory tier
1531+
// @param fromBgThread whether this function was called from a bg
1532+
// thread - this is used to decide whether bg thread should
1533+
// be waken in case there is no free memory
1534+
// @param evict whether to evict an item from tier tid in case there
1535+
// is not enough memory
15311536
WriteHandle allocateInternalTier(TierId tid,
15321537
PoolId id,
15331538
Key key,
15341539
uint32_t size,
15351540
uint32_t creationTime,
15361541
uint32_t expiryTime,
1537-
bool fromBgThread);
1542+
bool fromBgThread,
1543+
bool evict);
15381544

15391545
// Allocate a chained item
15401546
//
@@ -2977,7 +2983,8 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
29772983
uint32_t size,
29782984
uint32_t creationTime,
29792985
uint32_t expiryTime,
2980-
bool fromBgThread) {
2986+
bool fromBgThread,
2987+
bool evict) {
29812988
util::LatencyTracker tracker{stats().allocateLatency_};
29822989

29832990
SCOPE_FAIL { stats_.invalidAllocs.inc(); };
@@ -3002,6 +3009,9 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
30023009
}
30033010

30043011
if (memory == nullptr) {
3012+
if (!evict) {
3013+
return {};
3014+
}
30053015
memory = findEviction(tid, pid, cid);
30063016
}
30073017

@@ -3051,7 +3061,9 @@ CacheAllocator<CacheTrait>::allocateInternal(PoolId pid,
30513061
bool fromBgThread) {
30523062
auto tid = 0; /* TODO: consult admission policy */
30533063
for(TierId tid = 0; tid < getNumTiers(); ++tid) {
3054-
auto handle = allocateInternalTier(tid, pid, key, size, creationTime, expiryTime, fromBgThread);
3064+
bool evict = !config_.insertToFirstFreeTier || tid == getNumTiers() - 1;
3065+
auto handle = allocateInternalTier(tid, pid, key, size, creationTime,
3066+
expiryTime, fromBgThread, evict);
30553067
if (handle) return handle;
30563068
}
30573069
return {};
@@ -4220,13 +4232,16 @@ CacheAllocator<CacheTrait>::tryEvictToNextMemoryTier(
42204232

42214233
TierId nextTier = tid; // TODO - calculate this based on some admission policy
42224234
while (++nextTier < getNumTiers()) { // try to evict down to the next memory tiers
4235+
// always evict item from the nextTier to make room for new item
4236+
bool evict = true;
42234237
// allocateInternal might trigger another eviction
42244238
auto newItemHdl = allocateInternalTier(nextTier, pid,
42254239
item.getKey(),
42264240
item.getSize(),
42274241
item.getCreationTime(),
42284242
item.getExpiryTime(),
4229-
fromBgThread);
4243+
fromBgThread,
4244+
evict);
42304245

42314246
if (newItemHdl) {
42324247

@@ -4263,13 +4278,16 @@ CacheAllocator<CacheTrait>::tryPromoteToNextMemoryTier(
42634278
auto toPromoteTier = nextTier - 1;
42644279
--nextTier;
42654280

4281+
// always evict item from the toPromoteTier to make room for new item
4282+
bool evict = true;
42664283
// allocateInternal might trigger another eviction
42674284
auto newItemHdl = allocateInternalTier(toPromoteTier, pid,
42684285
item.getKey(),
42694286
item.getSize(),
42704287
item.getCreationTime(),
42714288
item.getExpiryTime(),
4272-
fromBgThread);
4289+
fromBgThread,
4290+
true);
42734291

42744292
if (newItemHdl) {
42754293
XDCHECK_EQ(newItemHdl->getSize(), item.getSize());
@@ -5608,6 +5626,7 @@ CacheAllocator<CacheTrait>::allocateNewItemForOldItem(const Item& oldItem) {
56085626
const auto tid = getTierId(oldItem);
56095627
const auto allocInfo =
56105628
allocator_[tid]->getAllocInfo(static_cast<const void*>(&oldItem));
5629+
bool evict = !config_.insertToFirstFreeTier || tid == getNumTiers() - 1;
56115630

56125631
// Set up the destination for the move. Since oldItem would have the moving
56135632
// bit set, it won't be picked for eviction.
@@ -5617,7 +5636,8 @@ CacheAllocator<CacheTrait>::allocateNewItemForOldItem(const Item& oldItem) {
56175636
oldItem.getSize(),
56185637
oldItem.getCreationTime(),
56195638
oldItem.getExpiryTime(),
5620-
false);
5639+
false,
5640+
evict);
56215641
if (!newItemHdl) {
56225642
return {};
56235643
}

cachelib/allocator/CacheAllocatorConfig.h

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

316+
// Insert items to first free memory tier
317+
CacheAllocatorConfig& enableInsertToFirstFreeTier();
318+
316319
// Passes in a callback to initialize an event tracker when the allocator
317320
// starts
318321
CacheAllocatorConfig& setEventTracker(EventTrackerSharedPtr&&);
@@ -539,6 +542,11 @@ class CacheAllocatorConfig {
539542
// ABOVE are the config for various cache workers
540543
//
541544

545+
// if turned off, always insert new elements to topmost memory tier.
546+
// if turned on, insert new element to first free memory tier or evict memory
547+
// from the bottom one if memory cache is full
548+
bool insertToFirstFreeTier = false;
549+
542550
// the number of tries to search for an item to evict
543551
// 0 means it's infinite
544552
unsigned int evictionSearchTries{50};
@@ -673,6 +681,12 @@ class CacheAllocatorConfig {
673681
{MemoryTierCacheConfig::fromShm().setRatio(1)}};
674682
};
675683

684+
template <typename T>
685+
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableInsertToFirstFreeTier() {
686+
insertToFirstFreeTier = true;
687+
return *this;
688+
}
689+
676690
template <typename T>
677691
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheName(
678692
const std::string& _cacheName) {
@@ -1254,6 +1268,7 @@ std::map<std::string, std::string> CacheAllocatorConfig<T>::serialize() const {
12541268
configMap["nvmAdmissionMinTTL"] = std::to_string(nvmAdmissionMinTTL);
12551269
configMap["delayCacheWorkersStart"] =
12561270
delayCacheWorkersStart ? "true" : "false";
1271+
configMap["insertToFirstFreeTier"] = std::to_string(insertToFirstFreeTier);
12571272
mergeWithPrefix(configMap, throttleConfig.serialize(), "throttleConfig");
12581273
mergeWithPrefix(configMap,
12591274
chainedItemAccessConfig.serialize(),

cachelib/cachebench/cache/Cache.h

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

581+
allocatorConfig_.insertToFirstFreeTier = config_.insertToFirstFreeTier;
582+
581583
auto cleanupGuard = folly::makeGuard([&] {
582584
if (!nvmCacheFilePath_.empty()) {
583585
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)