Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions cachelib/allocator/CacheAllocator-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,8 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
uint32_t size,
uint32_t creationTime,
uint32_t expiryTime,
bool fromBgThread) {
bool fromBgThread,
bool evict) {
util::LatencyTracker tracker{stats().allocateLatency_};

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

if (memory == nullptr) {
if (memory == nullptr && !evict) {
return {};
} else if (memory == nullptr) {
memory = findEviction(tid, pid, cid);
}

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

TierId nextTier = tid; // TODO - calculate this based on some admission policy
while (++nextTier < getNumTiers()) { // try to evict down to the next memory tiers
// always evict item from the nextTier to make room for new item
bool evict = true;

// allocateInternal might trigger another eviction
auto newItemHdl = allocateInternalTier(nextTier, pid,
item.getKey(),
item.getSize(),
item.getCreationTime(),
item.getExpiryTime(),
fromBgThread);
fromBgThread,
evict);

if (newItemHdl) {
XDCHECK_EQ(newItemHdl->getSize(), item.getSize());
Expand Down Expand Up @@ -1855,13 +1863,17 @@ CacheAllocator<CacheTrait>::tryPromoteToNextMemoryTier(
auto toPromoteTier = nextTier - 1;
--nextTier;

// always evict item from the toPromoteTier to make room for new item
bool evict = true;

// allocateInternal might trigger another eviction
auto newItemHdl = allocateInternalTier(toPromoteTier, pid,
item.getKey(),
item.getSize(),
item.getCreationTime(),
item.getExpiryTime(),
fromBgThread);
fromBgThread,
true);

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

const auto allocInfo =
allocator_[getTierId(oldItem)]->getAllocInfo(static_cast<const void*>(&oldItem));

bool evict = !config_.insertToFirstFreeTier || getTierId(oldItem) == getNumTiers() - 1;

// Set up the destination for the move. Since oldItem would have the moving
// bit set, it won't be picked for eviction.
Expand All @@ -3237,7 +3251,8 @@ CacheAllocator<CacheTrait>::allocateNewItemForOldItem(const Item& oldItem) {
oldItem.getSize(),
oldItem.getCreationTime(),
oldItem.getExpiryTime(),
false);
false,
evict);
if (!newItemHdl) {
return {};
}
Expand Down
8 changes: 7 additions & 1 deletion cachelib/allocator/CacheAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -1520,13 +1520,19 @@ class CacheAllocator : public CacheBase {
// For description see allocateInternal.
//
// @param tid id a memory tier
// @param fromBgThread whether this function was called from a bg
// thread - this is used to decide whether bg thread should
// be waken in case there is no free memory
// @param evict whether to evict an item from tier tid in case there
// is not enough memory
WriteHandle allocateInternalTier(TierId tid,
PoolId id,
Key key,
uint32_t size,
uint32_t creationTime,
uint32_t expiryTime,
bool fromBgThread);
bool fromBgThread,
bool evict);

// Allocate a chained item
//
Expand Down
15 changes: 15 additions & 0 deletions cachelib/allocator/CacheAllocatorConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ class CacheAllocatorConfig {
// Library team if you find yourself customizing this.
CacheAllocatorConfig& setThrottlerConfig(util::Throttler::Config config);

// Insert items to first free memory tier
CacheAllocatorConfig& enableInsertToFirstFreeTier();

// Passes in a callback to initialize an event tracker when the allocator
// starts
CacheAllocatorConfig& setEventTracker(EventTrackerSharedPtr&&);
Expand Down Expand Up @@ -522,6 +525,11 @@ class CacheAllocatorConfig {
// ABOVE are the config for various cache workers
//

// if turned off, always insert new elements to topmost memory tier.
// if turned on, insert new element to first free memory tier or evict memory
// from the bottom one if memory cache is full
bool insertToFirstFreeTier = false;

// the number of tries to search for an item to evict
// 0 means it's infinite
unsigned int evictionSearchTries{50};
Expand Down Expand Up @@ -657,6 +665,12 @@ class CacheAllocatorConfig {
{MemoryTierCacheConfig::fromShm().setRatio(1)}};
};

template <typename T>
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableInsertToFirstFreeTier() {
insertToFirstFreeTier = true;
return *this;
}

template <typename T>
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::setCacheName(
const std::string& _cacheName) {
Expand Down Expand Up @@ -1234,6 +1248,7 @@ std::map<std::string, std::string> CacheAllocatorConfig<T>::serialize() const {
configMap["nvmAdmissionMinTTL"] = std::to_string(nvmAdmissionMinTTL);
configMap["delayCacheWorkersStart"] =
delayCacheWorkersStart ? "true" : "false";
configMap["insertToFirstFreeTier"] = std::to_string(insertToFirstFreeTier);
mergeWithPrefix(configMap, throttleConfig.serialize(), "throttleConfig");
mergeWithPrefix(configMap,
chainedItemAccessConfig.serialize(),
Expand Down
2 changes: 2 additions & 0 deletions cachelib/cachebench/cache/Cache-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ Cache<Allocator>::Cache(const CacheConfig& config,
allocatorConfig_.configureMemoryTiers(config_.memoryTierConfigs);
}

allocatorConfig_.insertToFirstFreeTier = config_.insertToFirstFreeTier;

auto cleanupGuard = folly::makeGuard([&] {
if (!nvmCacheFilePath_.empty()) {
util::removePath(nvmCacheFilePath_);
Expand Down
2 changes: 2 additions & 0 deletions cachelib/cachebench/util/CacheConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ CacheConfig::CacheConfig(const folly::dynamic& configJson) {
JSONSetVal(configJson, tryLockUpdate);
JSONSetVal(configJson, lruIpSpec);
JSONSetVal(configJson, useCombinedLockForIterators);

JSONSetVal(configJson, insertToFirstFreeTier);

JSONSetVal(configJson, lru2qHotPct);
JSONSetVal(configJson, lru2qColdPct);
Expand Down
2 changes: 2 additions & 0 deletions cachelib/cachebench/util/CacheConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ struct CacheConfig : public JSONConfig {
bool lruUpdateOnRead{true};
bool tryLockUpdate{false};
bool useCombinedLockForIterators{true};

bool insertToFirstFreeTier{false};

// LRU param
uint64_t lruIpSpec{0};
Expand Down