Skip to content

Commit 27c6df2

Browse files
Hao Wufacebook-github-bot
Hao Wu
authored andcommitted
allow removeCb for item destruction
Summary: Allow to set either removeCb or item destructor in object cache. For object cache in hybrid cache, we'll utilize removeCb. Actually, all object cache should just use removeCb, because the tracking and freeing up memory should happen when the item leaves DRAM instead of the flash. Reviewed By: therealgymmy, lacora2017 Differential Revision: D58987552 fbshipit-source-id: 00a60e2bc817f1a462bde8c565626843d98ecaea
1 parent 0cc6082 commit 27c6df2

File tree

2 files changed

+72
-27
lines changed

2 files changed

+72
-27
lines changed

cachelib/object_cache/ObjectCache.h

+58-25
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class ObjectCache : public ObjectCacheBase<AllocatorT> {
146146

147147
public:
148148
using ItemDestructor = std::function<void(ObjectCacheDestructorData)>;
149+
using RemoveCb = std::function<void(ObjectCacheDestructorData)>;
149150
using Key = KAllocation::Key;
150151
using Config = ObjectCacheConfig<ObjectCache<AllocatorT>>;
151152
using EvictionPolicyConfig = typename AllocatorT::MMType::Config;
@@ -550,34 +551,66 @@ void ObjectCache<AllocatorT>::init() {
550551
.setDefaultAllocSizes({l1AllocSize})
551552
.enableItemReaperInBackground(config_.reaperInterval)
552553
.setEventTracker(std::move(config_.eventTracker))
553-
.setEvictionSearchLimit(config_.evictionSearchLimit)
554-
.setItemDestructor([this](typename AllocatorT::DestructorData data) {
555-
ObjectCacheDestructorContext ctx;
556-
if (data.context == DestructorContext::kEvictedFromRAM) {
557-
evictions_.inc();
558-
ctx = ObjectCacheDestructorContext::kEvicted;
559-
} else if (data.context == DestructorContext::kRemovedFromRAM) {
560-
ctx = ObjectCacheDestructorContext::kRemoved;
561-
} else { // should not enter here
562-
ctx = ObjectCacheDestructorContext::kUnknown;
563-
}
554+
.setEvictionSearchLimit(config_.evictionSearchLimit);
555+
if (config_.itemDestructor) {
556+
l1Config.setItemDestructor(
557+
[this](typename AllocatorT::DestructorData data) {
558+
ObjectCacheDestructorContext ctx;
559+
if (data.context == DestructorContext::kEvictedFromRAM) {
560+
evictions_.inc();
561+
ctx = ObjectCacheDestructorContext::kEvicted;
562+
} else if (data.context == DestructorContext::kRemovedFromRAM) {
563+
ctx = ObjectCacheDestructorContext::kRemoved;
564+
} else { // should not enter here
565+
ctx = ObjectCacheDestructorContext::kUnknown;
566+
}
564567

565-
auto& item = data.item;
568+
auto& item = data.item;
569+
570+
auto itemPtr = reinterpret_cast<ObjectCacheItem*>(item.getMemory());
571+
572+
SCOPE_EXIT {
573+
if (config_.objectSizeTrackingEnabled) {
574+
// update total object size
575+
totalObjectSizeBytes_.fetch_sub(itemPtr->objectSize,
576+
std::memory_order_relaxed);
577+
}
578+
// execute user defined item destructor
579+
config_.itemDestructor(ObjectCacheDestructorData(
580+
ctx, itemPtr->objectPtr, item.getKey(), item.getExpiryTime(),
581+
item.getCreationTime(), item.getLastAccessTime()));
582+
};
583+
});
584+
} else {
585+
l1Config.setRemoveCallback([this](typename AllocatorT::RemoveCbData data) {
586+
ObjectCacheDestructorContext ctx;
587+
if (data.context == RemoveContext::kEviction) {
588+
evictions_.inc();
589+
ctx = ObjectCacheDestructorContext::kEvicted;
590+
} else if (data.context == RemoveContext::kNormal) {
591+
ctx = ObjectCacheDestructorContext::kRemoved;
592+
} else { // should not enter here
593+
ctx = ObjectCacheDestructorContext::kUnknown;
594+
}
566595

567-
auto itemPtr = reinterpret_cast<ObjectCacheItem*>(item.getMemory());
596+
auto& item = data.item;
597+
598+
auto itemPtr = reinterpret_cast<ObjectCacheItem*>(item.getMemory());
599+
600+
SCOPE_EXIT {
601+
if (config_.objectSizeTrackingEnabled) {
602+
// update total object size
603+
totalObjectSizeBytes_.fetch_sub(itemPtr->objectSize,
604+
std::memory_order_relaxed);
605+
}
606+
// execute user defined item destructor
607+
config_.removeCb(ObjectCacheDestructorData(
608+
ctx, itemPtr->objectPtr, item.getKey(), item.getExpiryTime(),
609+
item.getCreationTime(), item.getLastAccessTime()));
610+
};
611+
});
612+
}
568613

569-
SCOPE_EXIT {
570-
if (config_.objectSizeTrackingEnabled) {
571-
// update total object size
572-
totalObjectSizeBytes_.fetch_sub(itemPtr->objectSize,
573-
std::memory_order_relaxed);
574-
}
575-
// execute user defined item destructor
576-
config_.itemDestructor(ObjectCacheDestructorData(
577-
ctx, itemPtr->objectPtr, item.getKey(), item.getExpiryTime(),
578-
item.getCreationTime(), item.getLastAccessTime()));
579-
};
580-
});
581614
if (config_.delayCacheWorkersStart) {
582615
l1Config.setDelayCacheWorkersStart();
583616
}

cachelib/object_cache/ObjectCacheConfig.h

+14-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct ObjectCacheConfig {
3232
using Key = KAllocation::Key;
3333
using EventTrackerSharedPtr = std::shared_ptr<EventInterface<Key>>;
3434
using ItemDestructor = typename ObjectCache::ItemDestructor;
35+
using RemoveCb = typename ObjectCache::RemoveCb;
3536
using SerializeCb = typename ObjectCache::SerializeCb;
3637
using DeserializeCb = typename ObjectCache::DeserializeCb;
3738
using EvictionPolicyConfig = typename ObjectCache::EvictionPolicyConfig;
@@ -106,6 +107,8 @@ struct ObjectCacheConfig {
106107
// });
107108
ObjectCacheConfig& setItemDestructor(ItemDestructor destructor);
108109

110+
ObjectCacheConfig& setRemoveCb(RemoveCb cb);
111+
109112
// Run in a multi-thread mode, eviction order is not guaranteed to persist.
110113
// @param threadCount number of threads to work on persistence
111114
// concurrently
@@ -197,6 +200,8 @@ struct ObjectCacheConfig {
197200
// or explicitly from cache
198201
ItemDestructor itemDestructor{};
199202

203+
RemoveCb removeCb{};
204+
200205
// time to sleep between each reaping period.
201206
std::chrono::milliseconds reaperInterval{5000};
202207

@@ -317,6 +322,12 @@ ObjectCacheConfig<T>& ObjectCacheConfig<T>::setItemDestructor(
317322
return *this;
318323
}
319324

325+
template <typename T>
326+
ObjectCacheConfig<T>& ObjectCacheConfig<T>::setRemoveCb(RemoveCb cb) {
327+
removeCb = std::move(cb);
328+
return *this;
329+
}
330+
320331
template <typename T>
321332
ObjectCacheConfig<T>& ObjectCacheConfig<T>::enablePersistence(
322333
uint32_t threadCount,
@@ -413,9 +424,10 @@ const ObjectCacheConfig<T>& ObjectCacheConfig<T>::validate() const {
413424
throw std::invalid_argument("l1EntriesLimit is not provided");
414425
}
415426

416-
if (!itemDestructor) {
427+
if ((!itemDestructor && !removeCb) || (itemDestructor && removeCb)) {
417428
throw std::invalid_argument(
418-
"ItemDestructor is mandatory, but not provided");
429+
"Only one of ItemDestructor or RemoveCb can be set. Not both, nor "
430+
"neither.");
419431
}
420432

421433
if (objectSizeTrackingEnabled) {

0 commit comments

Comments
 (0)