Skip to content

Commit 946b95b

Browse files
authored
Add option to insert items to first free tier (#87)
instead of always inserting to topmost tier
1 parent b90567d commit 946b95b

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
@@ -425,7 +425,8 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
425425
uint32_t size,
426426
uint32_t creationTime,
427427
uint32_t expiryTime,
428-
bool fromBgThread) {
428+
bool fromBgThread,
429+
bool evict) {
429430
util::LatencyTracker tracker{stats().allocateLatency_};
430431

431432
SCOPE_FAIL { stats_.invalidAllocs.inc(); };
@@ -446,7 +447,9 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
446447
backgroundEvictor_[backgroundWorkerId(tid, pid, cid, backgroundEvictor_.size())]->wakeUp();
447448
}
448449

449-
if (memory == nullptr) {
450+
if (memory == nullptr && !evict) {
451+
return {};
452+
} else if (memory == nullptr) {
450453
memory = findEviction(tid, pid, cid);
451454
}
452455

@@ -496,7 +499,8 @@ CacheAllocator<CacheTrait>::allocateInternal(PoolId pid,
496499
bool fromBgThread) {
497500
auto tid = 0; /* TODO: consult admission policy */
498501
for(TierId tid = 0; tid < getNumTiers(); ++tid) {
499-
auto handle = allocateInternalTier(tid, pid, key, size, creationTime, expiryTime, fromBgThread);
502+
bool evict = !config_.insertToFirstFreeTier || tid == getNumTiers() - 1;
503+
auto handle = allocateInternalTier(tid, pid, key, size, creationTime, expiryTime, fromBgThread, evict);
500504
if (handle) return handle;
501505
}
502506
return {};
@@ -1813,13 +1817,17 @@ CacheAllocator<CacheTrait>::tryEvictToNextMemoryTier(
18131817

18141818
TierId nextTier = tid; // TODO - calculate this based on some admission policy
18151819
while (++nextTier < getNumTiers()) { // try to evict down to the next memory tiers
1820+
// always evict item from the nextTier to make room for new item
1821+
bool evict = true;
1822+
18161823
// allocateInternal might trigger another eviction
18171824
auto newItemHdl = allocateInternalTier(nextTier, pid,
18181825
item.getKey(),
18191826
item.getSize(),
18201827
item.getCreationTime(),
18211828
item.getExpiryTime(),
1822-
fromBgThread);
1829+
fromBgThread,
1830+
evict);
18231831

18241832
if (newItemHdl) {
18251833
XDCHECK_EQ(newItemHdl->getSize(), item.getSize());
@@ -1855,13 +1863,17 @@ CacheAllocator<CacheTrait>::tryPromoteToNextMemoryTier(
18551863
auto toPromoteTier = nextTier - 1;
18561864
--nextTier;
18571865

1866+
// always evict item from the toPromoteTier to make room for new item
1867+
bool evict = true;
1868+
18581869
// allocateInternal might trigger another eviction
18591870
auto newItemHdl = allocateInternalTier(toPromoteTier, pid,
18601871
item.getKey(),
18611872
item.getSize(),
18621873
item.getCreationTime(),
18631874
item.getExpiryTime(),
1864-
fromBgThread);
1875+
fromBgThread,
1876+
true);
18651877

18661878
if (newItemHdl) {
18671879
XDCHECK_EQ(newItemHdl->getSize(), item.getSize());
@@ -3228,6 +3240,8 @@ CacheAllocator<CacheTrait>::allocateNewItemForOldItem(const Item& oldItem) {
32283240

32293241
const auto allocInfo =
32303242
allocator_[getTierId(oldItem)]->getAllocInfo(static_cast<const void*>(&oldItem));
3243+
3244+
bool evict = !config_.insertToFirstFreeTier || getTierId(oldItem) == getNumTiers() - 1;
32313245

32323246
// Set up the destination for the move. Since oldItem would have the moving
32333247
// bit set, it won't be picked for eviction.
@@ -3237,7 +3251,8 @@ CacheAllocator<CacheTrait>::allocateNewItemForOldItem(const Item& oldItem) {
32373251
oldItem.getSize(),
32383252
oldItem.getCreationTime(),
32393253
oldItem.getExpiryTime(),
3240-
false);
3254+
false,
3255+
evict);
32413256
if (!newItemHdl) {
32423257
return {};
32433258
}

cachelib/allocator/CacheAllocator.h

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

15311537
// Allocate a chained item
15321538
//

cachelib/allocator/CacheAllocatorConfig.h

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

312+
// Insert items to first free memory tier
313+
CacheAllocatorConfig& enableInsertToFirstFreeTier();
314+
312315
// Passes in a callback to initialize an event tracker when the allocator
313316
// starts
314317
CacheAllocatorConfig& setEventTracker(EventTrackerSharedPtr&&);
@@ -522,6 +525,11 @@ class CacheAllocatorConfig {
522525
// ABOVE are the config for various cache workers
523526
//
524527

528+
// if turned off, always insert new elements to topmost memory tier.
529+
// if turned on, insert new element to first free memory tier or evict memory
530+
// from the bottom one if memory cache is full
531+
bool insertToFirstFreeTier = false;
532+
525533
// the number of tries to search for an item to evict
526534
// 0 means it's infinite
527535
unsigned int evictionSearchTries{50};
@@ -657,6 +665,12 @@ class CacheAllocatorConfig {
657665
{MemoryTierCacheConfig::fromShm().setRatio(1)}};
658666
};
659667

668+
template <typename T>
669+
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableInsertToFirstFreeTier() {
670+
insertToFirstFreeTier = true;
671+
return *this;
672+
}
673+
660674
template <typename T>
661675
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheName(
662676
const std::string& _cacheName) {
@@ -1234,6 +1248,7 @@ std::map<std::string, std::string> CacheAllocatorConfig<T>::serialize() const {
12341248
configMap["nvmAdmissionMinTTL"] = std::to_string(nvmAdmissionMinTTL);
12351249
configMap["delayCacheWorkersStart"] =
12361250
delayCacheWorkersStart ? "true" : "false";
1251+
configMap["insertToFirstFreeTier"] = std::to_string(insertToFirstFreeTier);
12371252
mergeWithPrefix(configMap, throttleConfig.serialize(), "throttleConfig");
12381253
mergeWithPrefix(configMap,
12391254
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)