Skip to content

Commit 9212286

Browse files
rlyerlymeta-codesync[bot]
authored andcommitted
Small refactors in component API
Summary: Add some top level comments about CacheComponent & CacheItem. Add notes for the following important details: - Most APIs take string views of keys, the user needs to ensure the string view is constant until the API is finished - Components must call the item destructor in `release()` - Children of CacheItem must call the item destructor in `move()` (only needed if the inline buffer is used) The latter two clarifies responsibility for who calls the cache item destructor. Also remove setting handle.item_ to nullptr in the destructor, it's unnecessary because it only compensates for buggy implementations that double-free. Reviewed By: AlnisM Differential Revision: D102372138 fbshipit-source-id: 342fa1b347c24e2ec9f59b25f7144253c2732f0f
1 parent 9d07739 commit 9212286

5 files changed

Lines changed: 27 additions & 3 deletions

File tree

cachelib/interface/CacheComponent.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@
2525

2626
namespace facebook::cachelib::interface {
2727

28+
/**
29+
* A cache that manages a section of storage.
30+
*
31+
* The interface is as generic as possible to give components maximum
32+
* implementation flexibility. APIs are coro-compatible so components can run
33+
* work asynchronously (some components may run synchronously under the hood).
34+
*
35+
* NOTE: most APIs take the key argument as a Key (essentially a string view).
36+
* This allows maximum performance, but users *must* ensure the string view is
37+
* constant across coroutine suspension points.
38+
*/
2839
class CacheComponent {
2940
public:
3041
virtual ~CacheComponent() = default;
@@ -177,6 +188,8 @@ class CacheComponent {
177188
* executes any necessary callbacks. Only meant to be called by the component
178189
* or cache item handles.
179190
*
191+
* NOTE: the component is responsible for destroying the item!
192+
*
180193
* @param item the item to release
181194
* @param inserted whether the item was previously inserted into the cache
182195
* (callbacks are typically only called when it was inserted)

cachelib/interface/CacheItem.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ class CacheItem {
106106
virtual uint32_t getTotalSize() const noexcept = 0;
107107

108108
private:
109+
/**
110+
* Move the cache item to a new location in memory. Only used when the item is
111+
* embedded in a Handle that a user is moving.
112+
*
113+
* NOTE: move is responsible for destroying *this!
114+
*
115+
* @param dest new location of the cache item
116+
*/
109117
virtual void move(void* dest) noexcept = 0;
110118

111119
friend class Handle;

cachelib/interface/Handle.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ Handle::Handle(Handle&& other) noexcept
3737
XDCHECK_NE(cache_, nullptr) << "Invalid handle";
3838
if (other.item_ == reinterpret_cast<CacheItem*>(other.buf_)) {
3939
other.item_->move(buf_);
40-
other.item_->~CacheItem();
4140
item_ = reinterpret_cast<CacheItem*>(buf_);
4241
} else {
4342
item_ = other.item_;
@@ -50,7 +49,6 @@ Handle::~Handle() noexcept {
5049
if (item_->decrementRefCount()) {
5150
cache_->release(*item_, inserted_);
5251
}
53-
item_ = nullptr;
5452
}
5553
}
5654

cachelib/interface/components/FlashCacheComponent.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ class FlashCacheItem : public CacheItem {
150150

151151
void move(void* dest) noexcept override {
152152
new (dest) FlashCacheItem(std::move(*this));
153+
this->~FlashCacheItem();
153154
}
154155
};
155156

@@ -663,6 +664,7 @@ class ConsistentFlashCacheItem : public FlashCacheItem {
663664

664665
void move(void* dest) noexcept override {
665666
new (dest) ConsistentFlashCacheItem(std::move(*this));
667+
this->~ConsistentFlashCacheItem();
666668
}
667669
};
668670

cachelib/interface/components/RAMCacheComponent.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,10 @@ UnitResult RAMCacheComponent::writeBack(CacheItem& /* item */) {
399399
void RAMCacheComponent::release(interface::CacheItem& item, bool inserted) {
400400
stats_->release_.throughput_.calls_.inc();
401401
auto latencyGuard = stats_->release_.latency_.start();
402-
auto* implItem = reinterpret_cast<RAMCacheItem&>(item).item();
402+
auto& genericItem = reinterpret_cast<RAMCacheItem&>(item);
403+
auto* implItem = genericItem.item();
404+
// call this destructor first since genericItem is embedded in implItem
405+
genericItem.~RAMCacheItem();
403406
cache_->releaseBackToAllocator(*implItem, RemoveContext::kNormal,
404407
/* nascent */ !inserted);
405408
stats_->release_.throughput_.successes_.inc();

0 commit comments

Comments
 (0)