From 2b22c2f2e14c26a8c4dd3cccb7a323a361166beb Mon Sep 17 00:00:00 2001 From: Coldwings Date: Tue, 2 Jan 2024 12:29:58 +0800 Subject: [PATCH] refactoring templates Signed-off-by: Coldwings --- common/expirecontainer.h | 284 ++++++++++++++++----------------------- 1 file changed, 119 insertions(+), 165 deletions(-) diff --git a/common/expirecontainer.h b/common/expirecontainer.h index 8d3eeeec..b8ffe0f8 100644 --- a/common/expirecontainer.h +++ b/common/expirecontainer.h @@ -202,7 +202,7 @@ class ExpireList : public ExpireContainer { using Base = ExpireContainer; using Base::Base; using typename Base::Item; - bool keep_alive(const T& x, bool insert_if_not_exists) { + bool keep_alive(const T &x, bool insert_if_not_exists) { return Base::keep_alive(Item(x), insert_if_not_exists); } }; @@ -251,49 +251,14 @@ 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 { + template + class PtrItem : public KeyedItem { public: using KeyedItem::KeyedItem; + using typename KeyedItem::InterfaceKey; + using ValPtr = ValType; + using ValEntity = typename std::remove_pointer::type; virtual PtrItem* construct() const override { auto item = new PtrItem(this->_key); item->_obj = nullptr; @@ -302,14 +267,26 @@ class ObjectCacheBase : public ExpireContainerBase { return item; } ~PtrItem() override { delete (ValPtr)this->_obj; } + ValPtr get_ptr() { return (ValPtr)this->_obj; } + ValEntity& get_ref() { return *(ValPtr)this->_obj; } + + ValPtr get() { return get_ptr(); } + + static ValPtr create_default() { return new ValEntity(); } + template + static decltype(auto) initialize(const Ctor& ctor) { + return [&ctor](void* arg) { ((PtrItem*)arg)->_obj = ctor(); }; + } }; - template - class ListItem - : public KeyedItem { + template + class ListItem : public KeyedItem { public: + using ValPtr = ValType*; + using ValEntity = ValType; ValEntity _list; using KeyedItem::KeyedItem; + using typename KeyedItem::InterfaceKey; virtual ListItem* construct() const override { auto item = new ListItem(this->_key); item->_obj = nullptr; @@ -318,38 +295,59 @@ class ObjectCacheBase : public ExpireContainerBase { return item; } ~ListItem() { _list.delete_all(); } + ValPtr get_ptr() { return &this->_list; } + ValEntity& get_ref() { return this->_list; } + + ValEntity& get() { return get_ref(); } + + static ValEntity create_default() { return ValEntity(); } + template + static decltype(auto) initialize(const Ctor& ctor) { + return [&ctor](void* arg) { + ((ListItem*)arg)->_list = ctor(); + ((ListItem*)arg)->_obj = arg; + }; + } }; -}; -template -class ObjectCacheCommon : public ObjectCacheBase { -public: - using Base = ObjectCacheBase; - using KeyedItem = Base::KeyedItem; + template + class Borrow { + public: + using Item = typename ObjectCache::Item; + ObjectCache* _oc; + Item* _ref; + bool _recycle = false; - using ItemKey = typename KeyedItem::ItemKey; - using InterfaceKey = typename KeyedItem::InterfaceKey; - using Item = ItemType; - using ItemPtr = ItemType*; + Borrow(ObjectCache* oc, Item* ref, bool recycle) + : _oc(oc), _ref(ref), _recycle(recycle) {} + ~Borrow() { + if (_ref) _oc->ref_release(_ref, _recycle); + } - ObjectCacheCommon(uint64_t expiration) : Base(expiration, expiration / 16) {} - ObjectCacheCommon(uint64_t expiration, uint64_t timer_cycle) - : Base(expiration, timer_cycle) {} + Borrow() = delete; + Borrow(const Borrow&) = delete; + Borrow(Borrow&& rhs) { move(std::move(rhs)); } + void operator=(const Borrow&) = delete; + void operator=(Borrow&& rhs) { move(rhs); } - int ref_release(ItemPtr item, bool recycle = false) { - return Base::ref_release(item, recycle); - } + operator bool() const { return _ref; } - int release(const InterfaceKey& key, bool recycle = false) { - return Base::release(Item(key), recycle); - } + bool recycle() const { return _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)); - } + bool recycle(bool x) { return _recycle = x; } + + typename Item::ValPtr operator->() { return _ref->get_ptr(); } + typename Item::ValEntity& operator&() { return _ref->get_ref(); } + + protected: + void move(Borrow&& rhs) { + _oc = rhs._oc; + rhs._oc = nullptr; + _ref = rhs._ref; + rhs._ref = nullptr; + _recycle = rhs._recycle; + } + }; }; // Resource pool based on reference count @@ -358,126 +356,82 @@ class ObjectCacheCommon : public ObjectCacheBase { // or findout the object, add reference count; when object release, reduce // refcount. if some resource is not referenced, it will be put back to gc list // waiting to release. -template -class ObjectCache - : public ObjectCacheCommon< - KeyType, ValPtr, typename std::remove_pointer::type, - ObjectCache, ObjectCacheBase::PtrItem> { -protected: - using Item = ObjectCacheBase::PtrItem; +template +class __ObjectCache : public ObjectCacheBase { +public: using Base = ObjectCacheBase; - using Common = ObjectCacheCommon< - KeyType, ValPtr, typename std::remove_pointer::type, - ObjectCache, Item>; + using Item = ItemType; + using KeyedItem = Base::KeyedItem; using InterfaceKey = typename Item::InterfaceKey; using ItemPtr = Item*; - using ValEntity = typename std::remove_pointer::type; + using ValEntity = typename Item::ValEntity; + using Borrow = typename Base::Borrow<__ObjectCache>; -public: - using typename Common::iterator; - - using Common::Common; - using Common::release; - using Common::ref_release; - using Common::begin; - using Common::end; - using Common::find; + __ObjectCache(uint64_t expiration) : Base(expiration, expiration / 16) {} + __ObjectCache(uint64_t expiration, uint64_t timer_cycle) + : Base(expiration, timer_cycle) {} template ItemPtr ref_acquire(const InterfaceKey& key, const Constructor& ctor, uint64_t failure_cooldown = 0) { - auto _ctor = [&](void* item) { - ((Item*)item)->_obj = ctor(); - }; - // _ctor can always implicit cast to `Delegate` + auto _ctor = Item::initialize(ctor); return (ItemPtr)Base::ref_acquire(Item(key), _ctor, failure_cooldown); } template - ValPtr acquire(const InterfaceKey& key, const Constructor& ctor, - uint64_t failure_cooldown = 0) { + decltype(auto) acquire(const InterfaceKey& key, const Constructor& ctor, + uint64_t failure_cooldown = 0) { auto item = ref_acquire(key, ctor, failure_cooldown); - return (ValPtr)(item ? item->_obj : nullptr); + assert(item); + return item->get(); } - class Borrow: public Base::Borrow { - public: - using Base::Borrow::Borrow; - ValEntity& operator*() { return *Borrow::get_ptr(); } - ValPtr operator->() { return Borrow::get_ptr(); } - }; - - template - Borrow borrow(const InterfaceKey& key, const Constructor& ctor, - uint64_t failure_cooldown = 0) { - return Borrow(this, ref_acquire(key, ctor, failure_cooldown), false); + int ref_release(ItemPtr item, bool recycle = false) { + return Base::ref_release(item, recycle); } - Borrow borrow(const InterfaceKey& key) { - return borrow(key, [] { return new ValEntity(); }); + int release(const InterfaceKey& key, bool recycle = false) { + return Base::release(Item(key), recycle); } -}; - -template -class ObjectCache> - : public ObjectCacheCommon*, - intrusive_list, - ObjectCache>, - ObjectCacheBase::ListItem>> { -protected: - using ListType = intrusive_list; - using Item = ObjectCacheBase::ListItem; - using Base = ObjectCacheBase; - using Common = ObjectCacheCommon*, - intrusive_list, - ObjectCache>, - ObjectCacheBase::ListItem>>; - using InterfaceKey = typename Item::InterfaceKey; - using ItemPtr = Item*; - -public: - 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, - uint64_t failure_cooldown = 0) { - auto _ctor = [&](void* item) { - ((Item*)item)->_list = ctor(); - // always not nullptr - ((Item*)item)->_obj = item; - }; - return (ItemPtr)ObjectCacheBase::ref_acquire(Item(key), _ctor, failure_cooldown); + 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)); } template - ListType& acquire(const InterfaceKey& key, const Constructor& ctor, - uint64_t failure_cooldown = 0) { - auto item = ref_acquire(key, ctor, failure_cooldown); - assert(item); - return item->_list; + Borrow borrow(const typename Item::InterfaceKey& key, + const Constructor& ctor, uint64_t failure_cooldown = 0) { + return Borrow( + this, + ((__ObjectCache*)this)->ref_acquire(key, ctor, failure_cooldown), + false); } - class Borrow: public Base::Borrow { - public: - using Base::Borrow::Borrow; - ListType& operator*() { return *this->_ref->_list; } - ListType* operator->() { return &this->_ref->_list; } - }; - - template - Borrow borrow(const InterfaceKey& key, const Constructor& ctor, - uint64_t failure_cooldown = 0) { - return Borrow(this, ref_acquire(key, ctor, failure_cooldown), false); + Borrow borrow(const typename Item::InterfaceKey& key) { + return borrow(key, &Item::create_default); } +}; - Borrow borrow(const InterfaceKey& key) { - return borrow(key, [] { return ListType(); }); - } +template +class ObjectCache + : public __ObjectCache> { +public: + using __ObjectCache< + KeyType, ValPtr, + ObjectCacheBase::PtrItem>::__ObjectCache; +}; + +template +class ObjectCache> + : public __ObjectCache< + KeyType, intrusive_list, + ObjectCacheBase::ListItem>> { +public: + using __ObjectCache, + ObjectCacheBase::ListItem< + KeyType, intrusive_list>>::__ObjectCache; };