File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -30,11 +30,13 @@ class CacheItem {
3030 CacheItem () = default ;
3131 virtual ~CacheItem () = default ;
3232
33- // CacheItem is not copyable or movable
33+ // CacheItem is not copyable
3434 CacheItem (const CacheItem&) = delete ;
3535 CacheItem& operator =(const CacheItem&) = delete ;
36- CacheItem (CacheItem&&) = delete ;
37- CacheItem& operator =(CacheItem&&) = delete ;
36+
37+ // CacheItem is movable
38+ CacheItem (CacheItem&&) noexcept = default ;
39+ CacheItem& operator =(CacheItem&&) noexcept = default ;
3840
3941 // ------------------------------ Interface ------------------------------ //
4042
@@ -102,6 +104,11 @@ class CacheItem {
102104 * @return total size of cache item
103105 */
104106 virtual uint32_t getTotalSize () const noexcept = 0;
107+
108+ private:
109+ virtual void move (void * dest) noexcept = 0;
110+
111+ friend class Handle ;
105112};
106113
107114} // namespace facebook::cachelib::interface
Original file line number Diff line number Diff line change 1818
1919#include < folly/logging/xlog.h>
2020
21- #include < cstring>
22-
2321#include " cachelib/interface/CacheComponent.h"
2422
2523namespace facebook ::cachelib::interface {
@@ -38,7 +36,8 @@ Handle::Handle(Handle&& other) noexcept
3836 : cache_(other.cache_), inserted_(other.inserted_) {
3937 XDCHECK_NE (cache_, nullptr ) << " Invalid handle" ;
4038 if (other.item_ == reinterpret_cast <CacheItem*>(other.buf_ )) {
41- std::memcpy (buf_, other.buf_ , kInlineBufSize );
39+ other.item_ ->move (buf_);
40+ other.item_ ->~CacheItem ();
4241 item_ = reinterpret_cast <CacheItem*>(buf_);
4342 } else {
4443 item_ = other.item_ ;
Original file line number Diff line number Diff line change @@ -72,10 +72,6 @@ class Handle {
7272 * Note: the caller is responsible for incrementing the item's refcount after
7373 * allocating it in the inline buffer
7474 *
75- * Note: the Handle move constructor relocates inline items via memcpy. This
76- * is safe only if the item type has no self-referential pointers (i.e.,
77- * members that point to other members or to `this`).
78- *
7975 * @param cache the cache component that owns the cache item
8076 * @param inserted whether the cache item has been inserted into cache
8177 */
Original file line number Diff line number Diff line change @@ -147,6 +147,10 @@ class FlashCacheItem : public CacheItem {
147147 // Allocation and findToWrite paths use MutableBufferView (points into region
148148 // buffer). Find path uses Buffer (owned copy from device read).
149149 std::variant<Buffer, MutableBufferView> data_;
150+
151+ void move (void * dest) noexcept override {
152+ new (dest) FlashCacheItem (std::move (*this ));
153+ }
150154};
151155
152156static_assert (sizeof (FlashCacheItem) <= Handle::kInlineBufSize ,
@@ -656,6 +660,10 @@ class ConsistentFlashCacheItem : public FlashCacheItem {
656660
657661 private:
658662 utils::ShardedSerializer::WriteLock lock_;
663+
664+ void move (void * dest) noexcept override {
665+ new (dest) ConsistentFlashCacheItem (std::move (*this ));
666+ }
659667};
660668
661669static_assert (sizeof (ConsistentFlashCacheItem) <= Handle::kInlineBufSize ,
Original file line number Diff line number Diff line change @@ -91,6 +91,11 @@ class RAMCacheItem : public interface::CacheItem {
9191 LruCacheItem* item_;
9292
9393 explicit RAMCacheItem (LruCacheItem* item) : item_(item) {}
94+
95+ void move (void * /* dest */ ) noexcept override {
96+ // We don't use the inline Handle buffer, move() should never be called
97+ XLOG (FATAL) << " Should not use RAMCacheItem::move()" ;
98+ }
9499};
95100// RAMCacheItem should only contain vtable and LruCacheItem pointers
96101static_assert (sizeof (RAMCacheItem) == (2 * sizeof (void *)));
Original file line number Diff line number Diff line change @@ -55,6 +55,10 @@ class TestCacheItem : public CacheItem {
5555 std::string key_;
5656 std::vector<uint8_t > memory_;
5757 std::atomic_size_t refCount_;
58+
59+ void move (void * /* dest */ ) noexcept override {
60+ XLOG (FATAL) << " Should not use TestCacheItem::move()" ;
61+ }
5862};
5963
6064class TestCacheComponent : public CacheComponent {
You can’t perform that action at this time.
0 commit comments