diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:15 +0300 |
commit | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch) | |
tree | da2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /util/memory/pool.h | |
parent | 778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff) | |
download | ydb-72cb13b4aff9bc9cf22e49251bc8fd143f82538f.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 1 of 2.
Diffstat (limited to 'util/memory/pool.h')
-rw-r--r-- | util/memory/pool.h | 430 |
1 files changed, 215 insertions, 215 deletions
diff --git a/util/memory/pool.h b/util/memory/pool.h index 13c8b6b9ed..8802f4fb1b 100644 --- a/util/memory/pool.h +++ b/util/memory/pool.h @@ -1,19 +1,19 @@ #pragma once - -#include "alloc.h" - -#include <util/system/align.h> -#include <util/system/yassert.h> + +#include "alloc.h" + +#include <util/system/align.h> +#include <util/system/yassert.h> #include <util/generic/bitops.h> #include <util/generic/utility.h> -#include <util/generic/intrlist.h> +#include <util/generic/intrlist.h> #include <util/generic/strbuf.h> #include <util/generic/singleton.h> #include <new> #include <string> #include <utility> - + /** * Memory pool implements a memory allocation scheme that is very fast, but * limited in its usage. @@ -23,32 +23,32 @@ * can just drop them off into oblivion without calling any destructors, * provided that all associated memory was allocated on the pool. */ -class TMemoryPool { -private: +class TMemoryPool { +private: using TBlock = IAllocator::TBlock; - - class TChunk: public TIntrusiveListItem<TChunk> { - public: + + class TChunk: public TIntrusiveListItem<TChunk> { + public: inline TChunk(size_t len = 0) noexcept - : Cur_((char*)(this + 1)) - , Left_(len) - { + : Cur_((char*)(this + 1)) + , Left_(len) + { Y_ASSERT((((size_t)Cur_) % PLATFORM_DATA_ALIGN) == 0); - } - + } + inline void* Allocate(size_t len) noexcept { - if (Left_ >= len) { - char* ret = Cur_; - - Cur_ += len; - Left_ -= len; - - return ret; - } - + if (Left_ >= len) { + char* ret = Cur_; + + Cur_ += len; + Left_ -= len; + + return ret; + } + return nullptr; - } - + } + inline void* Allocate(size_t len, size_t align) noexcept { size_t pad = AlignUp(Cur_, align) - Cur_; @@ -61,68 +61,68 @@ private: } inline size_t BlockLength() const noexcept { - return (Cur_ + Left_) - (char*)this; - } - + return (Cur_ + Left_) - (char*)this; + } + inline size_t Used() const noexcept { - return Cur_ - (const char*)this; - } + return Cur_ - (const char*)this; + } inline size_t Left() const noexcept { - return Left_; - } - + return Left_; + } + inline const char* Data() const noexcept { - return (const char*)(this + 1); - } + return (const char*)(this + 1); + } inline char* Data() noexcept { - return (char*)(this + 1); - } + return (char*)(this + 1); + } inline size_t DataSize() const noexcept { - return Cur_ - Data(); - } + return Cur_ - Data(); + } inline void ResetChunk() noexcept { - size_t total = DataSize() + Left(); - Cur_ = Data(); - Left_ = total; - } - - private: - char* Cur_; - size_t Left_; - }; + size_t total = DataSize() + Left(); + Cur_ = Data(); + Left_ = total; + } + + private: + char* Cur_; + size_t Left_; + }; using TChunkList = TIntrusiveList<TChunk>; - -public: - class IGrowPolicy { - public: + +public: + class IGrowPolicy { + public: virtual ~IGrowPolicy() = default; - + virtual size_t Next(size_t prev) const noexcept = 0; - }; - - class TLinearGrow: public IGrowPolicy { - public: + }; + + class TLinearGrow: public IGrowPolicy { + public: size_t Next(size_t prev) const noexcept override { - return prev; - } - + return prev; + } + static IGrowPolicy* Instance() noexcept; - }; - - class TExpGrow: public IGrowPolicy { - public: + }; + + class TExpGrow: public IGrowPolicy { + public: size_t Next(size_t prev) const noexcept override { - return prev * 2; - } - + return prev * 2; + } + static IGrowPolicy* Instance() noexcept; - }; - + }; + struct TOptions { bool RoundUpToNextPowerOfTwo; TOptions() @@ -132,44 +132,44 @@ public: }; inline TMemoryPool(size_t initial, IGrowPolicy* grow = TExpGrow::Instance(), IAllocator* alloc = TDefaultAllocator::Instance(), const TOptions& options = TOptions()) - : Current_(&Empty_) - , BlockSize_(initial) - , GrowPolicy_(grow) - , Alloc_(alloc) + : Current_(&Empty_) + , BlockSize_(initial) + , GrowPolicy_(grow) + , Alloc_(alloc) , Options_(options) - , Origin_(initial) + , Origin_(initial) , MemoryAllocatedBeforeCurrent_(0) , MemoryWasteBeforeCurrent_(0) - { - } - + { + } + inline ~TMemoryPool() { - Clear(); - } + Clear(); + } - inline void* Allocate(size_t len) { - return RawAllocate(AlignUp<size_t>(len, PLATFORM_DATA_ALIGN)); - } + inline void* Allocate(size_t len) { + return RawAllocate(AlignUp<size_t>(len, PLATFORM_DATA_ALIGN)); + } inline void* Allocate(size_t len, size_t align) { return RawAllocate(AlignUp<size_t>(len, PLATFORM_DATA_ALIGN), align); } - template <typename T> - inline T* Allocate() { + template <typename T> + inline T* Allocate() { return (T*)this->Allocate(sizeof(T), alignof(T)); - } + } - template <typename T> + template <typename T> inline T* Allocate(size_t align) { return (T*)this->Allocate(sizeof(T), Max(align, alignof(T))); } template <typename T> - inline T* AllocateArray(size_t count) { + inline T* AllocateArray(size_t count) { return (T*)this->Allocate(sizeof(T) * count, alignof(T)); - } - + } + template <typename T> inline T* AllocateArray(size_t count, size_t align) { return (T*)this->Allocate(sizeof(T) * count, Max(align, alignof(T))); @@ -192,90 +192,90 @@ public: template <typename T, typename... Args> inline T* New(Args&&... args) { return new (Allocate<T>()) T(std::forward<Args>(args)...); - } - - template <typename T> - inline T* NewArray(size_t count) { + } + + template <typename T> + inline T* NewArray(size_t count) { T* arr = (T*)AllocateArray<T>(count); + + for (T *ptr = arr, *end = arr + count; ptr != end; ++ptr) { + new (ptr) T; + } - for (T *ptr = arr, *end = arr + count; ptr != end; ++ptr) { - new (ptr) T; - } - - return arr; - } + return arr; + } - template <typename TChar> - inline TChar* Append(const TChar* str) { + template <typename TChar> + inline TChar* Append(const TChar* str) { return Append(str, std::char_traits<TChar>::length(str) + 1); // include terminating zero byte - } + } - template <typename TChar> - inline TChar* Append(const TChar* str, size_t len) { + template <typename TChar> + inline TChar* Append(const TChar* str, size_t len) { TChar* ret = AllocateArray<TChar>(len); std::char_traits<TChar>::copy(ret, str, len); - return ret; - } + return ret; + } - template <typename TChar> + template <typename TChar> inline TBasicStringBuf<TChar> AppendString(const TBasicStringBuf<TChar>& buf) { return TBasicStringBuf<TChar>(Append(buf.data(), buf.size()), buf.size()); - } + } - template <typename TChar> + template <typename TChar> inline TBasicStringBuf<TChar> AppendCString(const TBasicStringBuf<TChar>& buf) { TChar* ret = static_cast<TChar*>(Allocate((buf.size() + 1) * sizeof(TChar))); - + std::char_traits<TChar>::copy(ret, buf.data(), buf.size()); *(ret + buf.size()) = 0; return TBasicStringBuf<TChar>(ret, buf.size()); - } + } inline size_t Available() const noexcept { - return Current_->Left(); - } - + return Current_->Left(); + } + inline void Clear() noexcept { - DoClear(false); - } - + DoClear(false); + } + inline void ClearKeepFirstChunk() noexcept { - DoClear(true); - } - + DoClear(true); + } + inline size_t MemoryAllocated() const noexcept { return MemoryAllocatedBeforeCurrent_ + (Current_ != &Empty_ ? Current_->Used() : 0); - } - + } + inline size_t MemoryWaste() const noexcept { return MemoryWasteBeforeCurrent_ + (Current_ != &Empty_ ? Current_->Left() : 0); - } - - template <class TOp> + } + + template <class TOp> inline void Traverse(TOp& op) const noexcept { - for (TChunkList::TConstIterator i = Chunks_.Begin(); i != Chunks_.End(); ++i) { - op(i->Data(), i->DataSize()); + for (TChunkList::TConstIterator i = Chunks_.Begin(); i != Chunks_.End(); ++i) { + op(i->Data(), i->DataSize()); } - } - - inline IAllocator* RealAllocator() const noexcept { - return Alloc_; - } - -protected: - inline void* RawAllocate(size_t len) { - void* ret = Current_->Allocate(len); - - if (ret) { - return ret; - } - - AddChunk(len); - - return Current_->Allocate(len); - } - + } + + inline IAllocator* RealAllocator() const noexcept { + return Alloc_; + } + +protected: + inline void* RawAllocate(size_t len) { + void* ret = Current_->Allocate(len); + + if (ret) { + return ret; + } + + AddChunk(len); + + return Current_->Allocate(len); + } + inline void* RawAllocate(size_t len, size_t align) { Y_ASSERT(align > 0); void* ret = Current_->Allocate(len, align); @@ -289,38 +289,38 @@ protected: return Current_->Allocate(len, align); } -private: - void AddChunk(size_t hint); - void DoClear(bool keepfirst) noexcept; +private: + void AddChunk(size_t hint); + void DoClear(bool keepfirst) noexcept; -private: - TChunk Empty_; - TChunk* Current_; - size_t BlockSize_; - IGrowPolicy* GrowPolicy_; - IAllocator* Alloc_; +private: + TChunk Empty_; + TChunk* Current_; + size_t BlockSize_; + IGrowPolicy* GrowPolicy_; + IAllocator* Alloc_; TOptions Options_; - TChunkList Chunks_; - const size_t Origin_; + TChunkList Chunks_; + const size_t Origin_; size_t MemoryAllocatedBeforeCurrent_; size_t MemoryWasteBeforeCurrent_; -}; - -template <typename TPool> +}; + +template <typename TPool> struct TPoolableBase { inline void* operator new(size_t bytes, TPool& pool) { return pool.Allocate(bytes); } - + inline void* operator new(size_t bytes, std::align_val_t align, TPool& pool) { return pool.Allocate(bytes, (size_t)align); } inline void operator delete(void*, size_t) noexcept { - } - + } + inline void operator delete(void*, TPool&) noexcept { - } + } private: inline void* operator new(size_t); // disallow default allocation @@ -329,30 +329,30 @@ private: struct TPoolable: public TPoolableBase<TMemoryPool> { }; -class TMemoryPoolAllocator: public IAllocator { -public: - inline TMemoryPoolAllocator(TMemoryPool* pool) - : Pool_(pool) - { - } - +class TMemoryPoolAllocator: public IAllocator { +public: + inline TMemoryPoolAllocator(TMemoryPool* pool) + : Pool_(pool) + { + } + TBlock Allocate(size_t len) override { - TBlock ret = {Pool_->Allocate(len), len}; - - return ret; - } - + TBlock ret = {Pool_->Allocate(len), len}; + + return ret; + } + void Release(const TBlock& block) override { - (void)block; - } - -private: - TMemoryPool* Pool_; -}; - + (void)block; + } + +private: + TMemoryPool* Pool_; +}; + template <class T, class TPool> class TPoolAllocBase { -public: +public: using pointer = T*; using const_pointer = const T*; using reference = T&; @@ -361,46 +361,46 @@ public: using difference_type = ptrdiff_t; using value_type = T; - inline TPoolAllocBase(TPool* pool) - : Pool_(pool) - { - } + inline TPoolAllocBase(TPool* pool) + : Pool_(pool) + { + } - template <typename TOther> - inline TPoolAllocBase(const TPoolAllocBase<TOther, TPool>& o) - : Pool_(o.GetPool()) - { - } + template <typename TOther> + inline TPoolAllocBase(const TPoolAllocBase<TOther, TPool>& o) + : Pool_(o.GetPool()) + { + } - inline T* allocate(size_t n) { + inline T* allocate(size_t n) { return (T*)Pool_->Allocate(n * sizeof(T), alignof(T)); - } + } - inline void deallocate(pointer /*p*/, size_t /*n*/) { - } + inline void deallocate(pointer /*p*/, size_t /*n*/) { + } - template <class T1> - struct rebind { + template <class T1> + struct rebind { using other = TPoolAllocBase<T1, TPool>; - }; + }; inline size_type max_size() const noexcept { - return size_type(-1) / sizeof(T); - } + return size_type(-1) / sizeof(T); + } template <typename... Args> inline void construct(pointer p, Args&&... args) { new (p) T(std::forward<Args>(args)...); - } + } inline void destroy(pointer p) noexcept { - (void)p; /* Make MSVC happy. */ - p->~T(); - } + (void)p; /* Make MSVC happy. */ + p->~T(); + } - inline TPool* GetPool() const { - return Pool_; - } + inline TPool* GetPool() const { + return Pool_; + } inline friend bool operator==(const TPoolAllocBase& l, const TPoolAllocBase& r) { return l.Pool_ == r.Pool_; @@ -410,11 +410,11 @@ public: return !(l == r); } -private: - TPool* Pool_; +private: + TPool* Pool_; }; -template <class T> +template <class T> using TPoolAlloc = TPoolAllocBase<T, TMemoryPool>; // Any type since it is supposed to be rebound anyway. |