From cac94f6b0c06c0d8223f378bee9b6b2bf1fc1211 Mon Sep 17 00:00:00 2001 From: Coldwings Date: Thu, 28 Dec 2023 13:27:06 +0800 Subject: [PATCH] Extract ObjectCache common code into ObjectCacheCommon Signed-off-by: Coldwings --- common/expirecontainer.cpp | 2 +- common/expirecontainer.h | 290 ++++++++++++++++++------------------- 2 files changed, 140 insertions(+), 152 deletions(-) diff --git a/common/expirecontainer.cpp b/common/expirecontainer.cpp index a28f2482..6bf68df9 100644 --- a/common/expirecontainer.cpp +++ b/common/expirecontainer.cpp @@ -152,7 +152,7 @@ int ObjectCacheBase::ref_release(ItemPtr item, bool recycle) { // the argument `key` plays the roles of (type-erased) key int ObjectCacheBase::release(const ObjectCacheBase::Item& key_item, bool recycle) { - auto item = find(key_item); + auto item = ExpireContainerBase::TypedIterator(Base::find(key_item)); if (item == end()) return -1; return ref_release(*item, recycle); } diff --git a/common/expirecontainer.h b/common/expirecontainer.h index 5d7642fc..b9e802a4 100644 --- a/common/expirecontainer.h +++ b/common/expirecontainer.h @@ -251,10 +251,105 @@ class ObjectCacheBase : public ExpireContainerBase { // the argument `key` plays the roles of (type-erased) key int release(const Item& key_item, bool recycle = false); + template + class Borrow { + public: + ObjectCache* _oc; + ItemPtr _ref; + bool _recycle = false; + + Borrow(ObjectCache* oc, ItemPtr ref, bool recycle) + : _oc(oc), _ref(ref), _recycle(recycle) {} + ~Borrow() { + if (_ref) _oc->ref_release(_ref, _recycle); + } + + Borrow() = delete; + Borrow(const Borrow&) = delete; + Borrow(Borrow&& rhs) { move(std::move(rhs)); } + void operator=(const Borrow&) = delete; + void operator=(Borrow&& rhs) { move(rhs); } + + operator bool() const { return _ref; } + + bool recycle() const { return _recycle; } + + bool recycle(bool x) { return _recycle = x; } + + protected: + ValPtr get_ptr() { return (ValPtr)_ref->_obj; } + void move(Borrow&& rhs) { + _oc = rhs._oc; + rhs._oc = nullptr; + _ref = rhs._ref; + rhs._ref = nullptr; + _recycle = rhs._recycle; + } + }; + +public: + template + class PtrItem + : public KeyedItem { + public: + using KeyedItem::KeyedItem; + virtual PtrItem* construct() const override { + auto item = new PtrItem(this->_key); + item->_obj = nullptr; + item->_refcnt = 0; + item->_recycle = nullptr; + return item; + } + ~PtrItem() override { delete (ValPtr)this->_obj; } + }; + + template + class ListItem + : public KeyedItem { + public: + ValEntity _list; + using KeyedItem::KeyedItem; + virtual ListItem* construct() const override { + auto item = new ListItem(this->_key); + item->_obj = nullptr; + item->_refcnt = 0; + item->_recycle = nullptr; + return item; + } + ~ListItem() { _list.delete_all(); } + }; +}; + +template +class ObjectCacheCommon : public ObjectCacheBase { +public: + using Base = ObjectCacheBase; + using KeyedItem = Base::KeyedItem; + + using ItemKey = typename KeyedItem::ItemKey; + using InterfaceKey = typename KeyedItem::InterfaceKey; + using Item = ItemType; + using ItemPtr = ItemType*; + + ObjectCacheCommon(uint64_t expiration) : Base(expiration, expiration / 16) {} + ObjectCacheCommon(uint64_t expiration, uint64_t timer_cycle) + : Base(expiration, timer_cycle) {} + + int ref_release(ItemPtr item, bool recycle = false) { + return Base::ref_release(item, recycle); + } + + int release(const InterfaceKey& key, bool recycle = false) { + return Base::release(Item(key), recycle); + } + using iterator = typename ExpireContainerBase::TypedIterator; iterator begin() { return Base::begin(); } iterator end() { return Base::end(); } - iterator find(const Item& key_item) { return Base::find(key_item); } + iterator find(const InterfaceKey& key) { + return Base::find(KeyedItem(key)); + } }; // Resource pool based on reference count @@ -264,32 +359,28 @@ class ObjectCacheBase : public ExpireContainerBase { // refcount. if some resource is not referenced, it will be put back to gc list // waiting to release. template -class ObjectCache : public ObjectCacheBase { +class ObjectCache + : public ObjectCacheCommon< + KeyType, ValPtr, typename std::remove_pointer::type, + ObjectCache, ObjectCacheBase::PtrItem> { protected: + using Item = ObjectCacheBase::PtrItem; using Base = ObjectCacheBase; - using ValEntity = typename std::remove_pointer::type; - using KeyedItem = Base::KeyedItem; - class Item : public KeyedItem { - public: - using KeyedItem::KeyedItem; - virtual Item* construct() const override { - auto item = new Item(this->_key); - item->_obj = nullptr; - item->_refcnt = 0; - item->_recycle = nullptr; - return item; - } - ~Item() override { delete (ValPtr)this->_obj; } - }; - - using ItemKey = typename Item::ItemKey; + using Common = ObjectCacheCommon< + KeyType, ValPtr, typename std::remove_pointer::type, + ObjectCache, Item>; using InterfaceKey = typename Item::InterfaceKey; using ItemPtr = Item*; + using ValEntity = typename std::remove_pointer::type; public: - ObjectCache(uint64_t expiration) : Base(expiration, expiration / 16) {} - ObjectCache(uint64_t expiration, uint64_t timer_cycle) - : Base(expiration, timer_cycle) {} + using Common::Common; + using Common::release; + using Common::ref_release; + using Common::iterator; + using Common::begin; + using Common::end; + using Common::find; template ItemPtr ref_acquire(const InterfaceKey& key, const Constructor& ctor, @@ -301,10 +392,6 @@ class ObjectCache : public ObjectCacheBase { return (ItemPtr)Base::ref_acquire(Item(key), _ctor, failure_cooldown); } - int ref_release(ItemPtr item, bool recycle = false) { - return Base::ref_release(item, recycle); - } - template ValPtr acquire(const InterfaceKey& key, const Constructor& ctor, uint64_t failure_cooldown = 0) { @@ -312,55 +399,11 @@ class ObjectCache : public ObjectCacheBase { return (ValPtr)(item ? item->_obj : nullptr); } - int release(const InterfaceKey& key, bool recycle = false) { - return Base::release(Item(key), recycle); - } - - using iterator = typename ExpireContainerBase::TypedIterator; - iterator begin() { return Base::begin(); } - iterator end() { return Base::end(); } - iterator find(const InterfaceKey& key) { - return Base::find(KeyedItem(key)); - } - - class Borrow { - ObjectCache* _oc; - ItemPtr _ref; - bool _recycle = false; - + class Borrow: public Base::Borrow { public: - Borrow(ObjectCache* oc, ItemPtr ref, bool recycle) - : _oc(oc), _ref(ref), _recycle(recycle) {} - ~Borrow() { - if (_ref) _oc->ref_release(_ref, _recycle); - } - - Borrow() = delete; - Borrow(const Borrow&) = delete; - Borrow(Borrow&& rhs) { move(std::move(rhs)); } - void operator=(const Borrow&) = delete; - void operator=(Borrow&& rhs) { move(rhs); } - - ValEntity& operator*() { return *get_ptr(); } - - ValPtr operator->() { return get_ptr(); } - - operator bool() const { return _ref; } - - bool recycle() const { return _recycle; } - - bool recycle(bool x) { return _recycle = x; } - - private: - ValPtr get_ptr() { return (ValPtr)_ref->_obj; } - - void move(Borrow&& rhs) { - _oc = rhs._oc; - rhs._oc = nullptr; - _ref = rhs._ref; - rhs._ref = nullptr; - _recycle = rhs._recycle; - } + using Base::Borrow::Borrow; + ValEntity& operator*() { return *Borrow::get_ptr(); } + ValPtr operator->() { return Borrow::get_ptr(); } }; template @@ -375,35 +418,31 @@ class ObjectCache : public ObjectCacheBase { }; template -class ObjectCache> : public ObjectCacheBase { +class ObjectCache> + : public ObjectCacheCommon*, + intrusive_list, + ObjectCache>, + ObjectCacheBase::ListItem>> { protected: using ListType = intrusive_list; + using Item = ObjectCacheBase::ListItem; using Base = ObjectCacheBase; - using KeyedItem = Base::KeyedItem; - - class Item : public KeyedItem { - public: - ListType _list; - using KeyedItem::KeyedItem; - virtual Item* construct() const override { - auto item = new Item(this->_key); - item->_obj = nullptr; - item->_refcnt = 0; - item->_recycle = nullptr; - return item; - } - ~Item() { - _list.delete_all(); - } - }; - - using ItemPtr = Item*; + using Common = ObjectCacheCommon*, + intrusive_list, + ObjectCache>, + ObjectCacheBase::ListItem>>; using InterfaceKey = typename Item::InterfaceKey; + using ItemPtr = Item*; public: - ObjectCache(uint64_t expiration) : Base(expiration, expiration / 16) {} - ObjectCache(uint64_t expiration, uint64_t timer_cycle) - : Base(expiration, timer_cycle) {} + using typename Common::iterator; + + using Common::Common; + using Common::release; + using Common::ref_release; + using Common::begin; + using Common::end; + using Common::find; template ItemPtr ref_acquire(const InterfaceKey& key, const Constructor& ctor, @@ -416,9 +455,6 @@ class ObjectCache> : public ObjectCacheBase { return (ItemPtr)ObjectCacheBase::ref_acquire(Item(key), _ctor, failure_cooldown); } - // Constructor must be a function which returns a list - // and should return an non-empty list - // Empty list will be treated as construct failure. template ListType& acquire(const InterfaceKey& key, const Constructor& ctor, uint64_t failure_cooldown = 0) { @@ -427,59 +463,11 @@ class ObjectCache> : public ObjectCacheBase { return item->_list; } - int ref_release(ItemPtr item, bool recycle = false) { - return ObjectCacheBase::ref_release(item, recycle); - } - - int release(const InterfaceKey& key, bool recycle = false) { - return ObjectCacheBase::release(Item(key), recycle); - } - - using iterator = typename ExpireContainerBase::TypedIterator; - iterator begin() { return ObjectCacheBase::begin(); } - iterator end() { return ObjectCacheBase::end(); } - iterator find(const InterfaceKey& key) { - return ObjectCacheBase::find(KeyedItem(key)); - } - - class Borrow { - ObjectCache* _oc; - ItemPtr _ref; - bool _recycle = false; - + class Borrow: public Base::Borrow { public: - Borrow(ObjectCache* oc, ItemPtr ref, bool recycle) - : _oc(oc), _ref(ref), _recycle(recycle) {} - ~Borrow() { - if (_ref) _oc->ref_release(_ref, _recycle); - } - - Borrow() = delete; - Borrow(const Borrow&) = delete; - Borrow(Borrow&& rhs) { move(std::move(rhs)); } - void operator=(const Borrow&) = delete; - void operator=(Borrow&& rhs) { move(rhs); } - - ListType& operator*() { return get_ptr(); } - - ListType* operator->() { return &get_ptr(); } - - operator bool() const { return _ref; } - - bool recycle() const { return _recycle; } - - bool recycle(bool x) { return _recycle = x; } - - private: - ListType& get_ptr() { return _ref->_list; } - - void move(Borrow&& rhs) { - _oc = rhs._oc; - rhs._oc = nullptr; - _ref = rhs._ref; - rhs._ref = nullptr; - _recycle = rhs._recycle; - } + using Base::Borrow::Borrow; + ListType& operator*() { return *this->_ref->_list; } + ListType* operator->() { return &this->_ref->_list; } }; template