aboutsummaryrefslogtreecommitdiffstats
path: root/util/memory
diff options
context:
space:
mode:
authorAnton Samokhvalov <pg83@yandex.ru>2022-02-10 16:45:17 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:17 +0300
commitd3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch)
treedd4bd3ca0f36b817e96812825ffaf10d645803f2 /util/memory
parent72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff)
downloadydb-d3a398281c6fd1d3672036cb2d63f842d2cb28c5.tar.gz
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 2 of 2.
Diffstat (limited to 'util/memory')
-rw-r--r--util/memory/addstorage.cpp2
-rw-r--r--util/memory/addstorage.h90
-rw-r--r--util/memory/addstorage_ut.cpp46
-rw-r--r--util/memory/alloc.cpp38
-rw-r--r--util/memory/alloc.h40
-rw-r--r--util/memory/benchmark/pool/main.cpp20
-rw-r--r--util/memory/benchmark/ya.make2
-rw-r--r--util/memory/blob.cpp430
-rw-r--r--util/memory/blob.h262
-rw-r--r--util/memory/blob_ut.cpp122
-rw-r--r--util/memory/mmapalloc.cpp62
-rw-r--r--util/memory/mmapalloc.h14
-rw-r--r--util/memory/pool.cpp76
-rw-r--r--util/memory/pool.h430
-rw-r--r--util/memory/pool_ut.cpp150
-rw-r--r--util/memory/segmented_string_pool.cpp2
-rw-r--r--util/memory/segmented_string_pool.h82
-rw-r--r--util/memory/segpool_alloc.cpp2
-rw-r--r--util/memory/segpool_alloc.h52
-rw-r--r--util/memory/smallobj.cpp2
-rw-r--r--util/memory/smallobj.h182
-rw-r--r--util/memory/smallobj_ut.cpp126
-rw-r--r--util/memory/tempbuf.cpp484
-rw-r--r--util/memory/tempbuf.h132
-rw-r--r--util/memory/tempbuf_ut.cpp116
-rw-r--r--util/memory/ut/ya.make12
26 files changed, 1488 insertions, 1488 deletions
diff --git a/util/memory/addstorage.cpp b/util/memory/addstorage.cpp
index 32c7eb0a8f..0fe4b1465f 100644
--- a/util/memory/addstorage.cpp
+++ b/util/memory/addstorage.cpp
@@ -1 +1 @@
-#include "addstorage.h"
+#include "addstorage.h"
diff --git a/util/memory/addstorage.h b/util/memory/addstorage.h
index e335fcdeca..597c73a988 100644
--- a/util/memory/addstorage.h
+++ b/util/memory/addstorage.h
@@ -1,81 +1,81 @@
#pragma once
-
-#include <util/system/align.h>
+
+#include <util/system/align.h>
#include <util/system/defaults.h>
-
-#include <new>
-
+
+#include <new>
+
namespace NPrivate {
class TAdditionalStorageInfo {
- public:
+ public:
constexpr TAdditionalStorageInfo(size_t length) noexcept
: Length_(length)
{
- }
-
+ }
+
constexpr size_t Length() const noexcept {
return Length_;
- }
-
- private:
+ }
+
+ private:
size_t Length_;
- };
+ };
}
-
+
template <class T>
class alignas(::NPrivate::TAdditionalStorageInfo) TAdditionalStorage {
using TInfo = ::NPrivate::TAdditionalStorageInfo;
-public:
+public:
inline TAdditionalStorage() noexcept = default;
-
+
inline ~TAdditionalStorage() = default;
-
- inline void* operator new(size_t len1, size_t len2) {
+
+ inline void* operator new(size_t len1, size_t len2) {
static_assert(alignof(T) >= alignof(TInfo));
Y_ASSERT(len1 == sizeof(T));
void* data = ::operator new(CombinedSizeOfInstanceWithTInfo() + len2);
void* info = InfoPtr(static_cast<T*>(data));
Y_UNUSED(new (info) TInfo(len2));
-
+
return data;
- }
-
+ }
+
inline void operator delete(void* ptr) noexcept {
- DoDelete(ptr);
- }
-
+ DoDelete(ptr);
+ }
+
inline void operator delete(void* ptr, size_t) noexcept {
- DoDelete(ptr);
- }
-
+ DoDelete(ptr);
+ }
+
inline void operator delete(void* ptr, size_t, size_t) noexcept {
- /*
- * this delete operator can be called automagically by compiler
- */
-
- DoDelete(ptr);
- }
-
+ /*
+ * this delete operator can be called automagically by compiler
+ */
+
+ DoDelete(ptr);
+ }
+
inline void* AdditionalData() const noexcept {
return (char*)(static_cast<const T*>(this)) + CombinedSizeOfInstanceWithTInfo();
- }
-
+ }
+
static inline T* ObjectFromData(void* data) noexcept {
return reinterpret_cast<T*>(static_cast<char*>(data) - CombinedSizeOfInstanceWithTInfo());
- }
-
+ }
+
inline size_t AdditionalDataLength() const noexcept {
return InfoPtr(static_cast<const T*>(this))->Length();
- }
-
-private:
+ }
+
+private:
static inline void DoDelete(void* ptr) noexcept {
TInfo* info = InfoPtr(static_cast<T*>(ptr));
- info->~TInfo();
+ info->~TInfo();
::operator delete(ptr);
- }
-
+ }
+
static constexpr size_t CombinedSizeOfInstanceWithTInfo() noexcept {
return AlignUp(sizeof(T), alignof(TInfo)) + sizeof(TInfo);
}
@@ -88,6 +88,6 @@ private:
return reinterpret_cast<const TInfo*>(reinterpret_cast<const char*>(instance) + CombinedSizeOfInstanceWithTInfo() - sizeof(TInfo));
}
-private:
+private:
void* operator new(size_t) = delete;
-};
+};
diff --git a/util/memory/addstorage_ut.cpp b/util/memory/addstorage_ut.cpp
index 94d5c4df06..9b0c4989ab 100644
--- a/util/memory/addstorage_ut.cpp
+++ b/util/memory/addstorage_ut.cpp
@@ -1,24 +1,24 @@
-#include "addstorage.h"
-
+#include "addstorage.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
-class TAddStorageTest: public TTestBase {
- UNIT_TEST_SUITE(TAddStorageTest);
- UNIT_TEST(TestIt)
- UNIT_TEST_SUITE_END();
-
- class TClass: public TAdditionalStorage<TClass> {
- };
-
-private:
- inline void TestIt() {
- THolder<TClass> c(new (100) TClass);
-
- UNIT_ASSERT_EQUAL(c->AdditionalDataLength(), 100);
-
- //test segfault
- memset(c->AdditionalData(), 0, c->AdditionalDataLength());
- }
-};
-
-UNIT_TEST_SUITE_REGISTRATION(TAddStorageTest);
+
+class TAddStorageTest: public TTestBase {
+ UNIT_TEST_SUITE(TAddStorageTest);
+ UNIT_TEST(TestIt)
+ UNIT_TEST_SUITE_END();
+
+ class TClass: public TAdditionalStorage<TClass> {
+ };
+
+private:
+ inline void TestIt() {
+ THolder<TClass> c(new (100) TClass);
+
+ UNIT_ASSERT_EQUAL(c->AdditionalDataLength(), 100);
+
+ //test segfault
+ memset(c->AdditionalData(), 0, c->AdditionalDataLength());
+ }
+};
+
+UNIT_TEST_SUITE_REGISTRATION(TAddStorageTest);
diff --git a/util/memory/alloc.cpp b/util/memory/alloc.cpp
index 50ccb1b25d..49f012d857 100644
--- a/util/memory/alloc.cpp
+++ b/util/memory/alloc.cpp
@@ -1,20 +1,20 @@
-#include "alloc.h"
-
-#include <util/generic/singleton.h>
-#include <util/system/sys_alloc.h>
-
-using TBlock = TDefaultAllocator::TBlock;
-
-TBlock TDefaultAllocator::Allocate(size_t len) {
- TBlock ret = {y_allocate(len), len};
-
- return ret;
-}
-
-void TDefaultAllocator::Release(const TBlock& block) {
- y_deallocate(block.Data);
-}
-
+#include "alloc.h"
+
+#include <util/generic/singleton.h>
+#include <util/system/sys_alloc.h>
+
+using TBlock = TDefaultAllocator::TBlock;
+
+TBlock TDefaultAllocator::Allocate(size_t len) {
+ TBlock ret = {y_allocate(len), len};
+
+ return ret;
+}
+
+void TDefaultAllocator::Release(const TBlock& block) {
+ y_deallocate(block.Data);
+}
+
IAllocator* TDefaultAllocator::Instance() noexcept {
- return SingletonWithPriority<TDefaultAllocator, 0>();
-}
+ return SingletonWithPriority<TDefaultAllocator, 0>();
+}
diff --git a/util/memory/alloc.h b/util/memory/alloc.h
index 51c5a8e50b..d59575aef5 100644
--- a/util/memory/alloc.h
+++ b/util/memory/alloc.h
@@ -1,27 +1,27 @@
#pragma once
-#include <memory>
-
-template <class Allocator, class T>
+#include <memory>
+
+template <class Allocator, class T>
using TReboundAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<T>;
-
-class IAllocator {
-public:
- struct TBlock {
- void* Data;
- size_t Len;
- };
-
+
+class IAllocator {
+public:
+ struct TBlock {
+ void* Data;
+ size_t Len;
+ };
+
virtual ~IAllocator() = default;
-
- virtual TBlock Allocate(size_t len) = 0;
- virtual void Release(const TBlock& block) = 0;
-};
-
-class TDefaultAllocator: public IAllocator {
-public:
+
+ virtual TBlock Allocate(size_t len) = 0;
+ virtual void Release(const TBlock& block) = 0;
+};
+
+class TDefaultAllocator: public IAllocator {
+public:
TBlock Allocate(size_t len) override;
void Release(const TBlock& block) override;
-
+
static IAllocator* Instance() noexcept;
-};
+};
diff --git a/util/memory/benchmark/pool/main.cpp b/util/memory/benchmark/pool/main.cpp
index 1dcbc55b7b..0b4d6c94af 100644
--- a/util/memory/benchmark/pool/main.cpp
+++ b/util/memory/benchmark/pool/main.cpp
@@ -4,17 +4,17 @@
#include <util/generic/xrange.h>
#include <util/stream/output.h>
-#define BENCHMARK_POOL_ALLOC(chunkSize, allocSize, allocAlign) \
+#define BENCHMARK_POOL_ALLOC(chunkSize, allocSize, allocAlign) \
Y_CPU_BENCHMARK(MemroyPool_chunk##chunkSize##_alloc##allocSize##_align##allocAlign, p) { \
- TMemoryPool pool(chunkSize); \
- for (auto i : xrange<size_t>(0, p.Iterations())) { \
- (void)i; \
- Y_DO_NOT_OPTIMIZE_AWAY(pool.Allocate(allocSize, allocAlign)); \
- } \
- /* \
- Cerr << "Allocated: " << pool.MemoryAllocated() << Endl; \
- Cerr << "Waste: " << pool.MemoryWaste() << Endl; \
- */ \
+ TMemoryPool pool(chunkSize); \
+ for (auto i : xrange<size_t>(0, p.Iterations())) { \
+ (void)i; \
+ Y_DO_NOT_OPTIMIZE_AWAY(pool.Allocate(allocSize, allocAlign)); \
+ } \
+ /* \
+ Cerr << "Allocated: " << pool.MemoryAllocated() << Endl; \
+ Cerr << "Waste: " << pool.MemoryWaste() << Endl; \
+ */ \
}
BENCHMARK_POOL_ALLOC(4096, 1, 1)
diff --git a/util/memory/benchmark/ya.make b/util/memory/benchmark/ya.make
index f81bb6de21..2259b9434e 100644
--- a/util/memory/benchmark/ya.make
+++ b/util/memory/benchmark/ya.make
@@ -3,5 +3,5 @@ SUBSCRIBER(g:util-subscribers)
RECURSE(
pool
- pool/metrics
+ pool/metrics
)
diff --git a/util/memory/blob.cpp b/util/memory/blob.cpp
index 08e3964dab..91da5cadca 100644
--- a/util/memory/blob.cpp
+++ b/util/memory/blob.cpp
@@ -1,225 +1,225 @@
-#include "blob.h"
-#include "addstorage.h"
-
-#include <util/system/yassert.h>
-#include <util/system/filemap.h>
+#include "blob.h"
+#include "addstorage.h"
+
+#include <util/system/yassert.h>
+#include <util/system/filemap.h>
#include <util/system/mlock.h>
#include <util/stream/buffer.h>
#include <util/generic/ptr.h>
#include <util/generic/string.h>
-#include <util/generic/buffer.h>
-#include <util/generic/ylimits.h>
-#include <util/generic/singleton.h>
+#include <util/generic/buffer.h>
+#include <util/generic/ylimits.h>
+#include <util/generic/singleton.h>
#include <util/generic/yexception.h>
-
-template <class TCounter>
-class TDynamicBlobBase: public TBlob::TBase,
- public TRefCounted<TDynamicBlobBase<TCounter>, TCounter>,
- public TAdditionalStorage<TDynamicBlobBase<TCounter>> {
+
+template <class TCounter>
+class TDynamicBlobBase: public TBlob::TBase,
+ public TRefCounted<TDynamicBlobBase<TCounter>, TCounter>,
+ public TAdditionalStorage<TDynamicBlobBase<TCounter>> {
using TRefBase = TRefCounted<TDynamicBlobBase, TCounter>;
-
-public:
+
+public:
inline TDynamicBlobBase() = default;
-
+
~TDynamicBlobBase() override = default;
-
+
void Ref() noexcept override {
- TRefBase::Ref();
- }
-
+ TRefBase::Ref();
+ }
+
void UnRef() noexcept override {
- TRefBase::UnRef();
- }
-
+ TRefBase::UnRef();
+ }
+
inline void* Data() const noexcept {
- return this->AdditionalData();
- }
-
+ return this->AdditionalData();
+ }
+
inline size_t Length() const noexcept {
- return this->AdditionalDataLength();
- }
-};
-
-template <class TCounter>
-class TBufferBlobBase: public TBlob::TBase, public TRefCounted<TBufferBlobBase<TCounter>, TCounter> {
+ return this->AdditionalDataLength();
+ }
+};
+
+template <class TCounter>
+class TBufferBlobBase: public TBlob::TBase, public TRefCounted<TBufferBlobBase<TCounter>, TCounter> {
using TRefBase = TRefCounted<TBufferBlobBase, TCounter>;
-
-public:
- inline TBufferBlobBase(TBuffer& buf) {
- Buf_.Swap(buf);
- }
-
+
+public:
+ inline TBufferBlobBase(TBuffer& buf) {
+ Buf_.Swap(buf);
+ }
+
~TBufferBlobBase() override = default;
-
+
void Ref() noexcept override {
- TRefBase::Ref();
- }
-
+ TRefBase::Ref();
+ }
+
void UnRef() noexcept override {
- TRefBase::UnRef();
- }
-
+ TRefBase::UnRef();
+ }
+
inline const TBuffer& Buffer() const noexcept {
- return Buf_;
- }
-
-private:
- TBuffer Buf_;
-};
-
-template <class TCounter>
-class TStringBlobBase: public TBlob::TBase, public TRefCounted<TStringBlobBase<TCounter>, TCounter> {
+ return Buf_;
+ }
+
+private:
+ TBuffer Buf_;
+};
+
+template <class TCounter>
+class TStringBlobBase: public TBlob::TBase, public TRefCounted<TStringBlobBase<TCounter>, TCounter> {
using TRefBase = TRefCounted<TStringBlobBase, TCounter>;
-
-public:
+
+public:
inline TStringBlobBase(const TString& s)
- : S_(s)
- {
- }
-
+ : S_(s)
+ {
+ }
+
TStringBlobBase(TString&& s) noexcept
: S_(std::move(s))
{
}
~TStringBlobBase() override = default;
-
+
void Ref() noexcept override {
- TRefBase::Ref();
- }
-
+ TRefBase::Ref();
+ }
+
void UnRef() noexcept override {
- TRefBase::UnRef();
- }
-
+ TRefBase::UnRef();
+ }
+
inline const TString& String() const noexcept {
- return S_;
- }
-
-private:
+ return S_;
+ }
+
+private:
const TString S_;
-};
-
-template <class TCounter>
-class TMappedBlobBase: public TBlob::TBase, public TRefCounted<TMappedBlobBase<TCounter>, TCounter> {
+};
+
+template <class TCounter>
+class TMappedBlobBase: public TBlob::TBase, public TRefCounted<TMappedBlobBase<TCounter>, TCounter> {
using TRefBase = TRefCounted<TMappedBlobBase<TCounter>, TCounter>;
-
-public:
+
+public:
inline TMappedBlobBase(const TMemoryMap& map, ui64 offset, size_t len, EMappingMode mode)
- : Map_(map)
+ : Map_(map)
, Mode_(mode)
- {
+ {
Y_ENSURE(Map_.IsOpen(), TStringBuf("memory map not open"));
-
- Map_.Map(offset, len);
-
- if (len && !Map_.Ptr()) { // Ptr is 0 for blob of size 0
- ythrow yexception() << "can not map(" << offset << ", " << len << ")";
- }
+
+ Map_.Map(offset, len);
+
+ if (len && !Map_.Ptr()) { // Ptr is 0 for blob of size 0
+ ythrow yexception() << "can not map(" << offset << ", " << len << ")";
+ }
if (Mode_ == EMappingMode::Locked) {
LockMemory(Data(), Length());
- }
- }
-
+ }
+ }
+
~TMappedBlobBase() override {
if (Mode_ == EMappingMode::Locked && Length()) {
UnlockMemory(Data(), Length());
- }
+ }
}
-
+
void Ref() noexcept override {
- TRefBase::Ref();
- }
-
+ TRefBase::Ref();
+ }
+
void UnRef() noexcept override {
- TRefBase::UnRef();
- }
-
+ TRefBase::UnRef();
+ }
+
inline const void* Data() const noexcept {
- return Map_.Ptr();
- }
-
+ return Map_.Ptr();
+ }
+
inline size_t Length() const noexcept {
- return Map_.MappedSize();
- }
-
-private:
- TFileMap Map_;
+ return Map_.MappedSize();
+ }
+
+private:
+ TFileMap Map_;
EMappingMode Mode_;
-};
-
-TBlob TBlob::SubBlob(size_t len) const {
- /*
- * may be slightly optimized
- */
-
- return SubBlob(0, len);
-}
-
-TBlob TBlob::SubBlob(size_t begin, size_t end) const {
- if (begin > Length() || end > Length() || begin > end) {
+};
+
+TBlob TBlob::SubBlob(size_t len) const {
+ /*
+ * may be slightly optimized
+ */
+
+ return SubBlob(0, len);
+}
+
+TBlob TBlob::SubBlob(size_t begin, size_t end) const {
+ if (begin > Length() || end > Length() || begin > end) {
ythrow yexception() << "incorrect subblob (" << begin << ", " << end << ", outer length = " << Length() << ")";
- }
-
- return TBlob(Begin() + begin, end - begin, S_.Base);
-}
-
-TBlob TBlob::DeepCopy() const {
+ }
+
+ return TBlob(Begin() + begin, end - begin, S_.Base);
+}
+
+TBlob TBlob::DeepCopy() const {
return TBlob::Copy(Data(), Length());
-}
-
-template <class TCounter>
-static inline TBlob CopyConstruct(const void* data, size_t len) {
+}
+
+template <class TCounter>
+static inline TBlob CopyConstruct(const void* data, size_t len) {
using Base = TDynamicBlobBase<TCounter>;
- THolder<Base> base(new (len) Base);
-
+ THolder<Base> base(new (len) Base);
+
Y_ASSERT(base->Length() == len);
-
- memcpy(base->Data(), data, len);
-
- TBlob ret(base->Data(), len, base.Get());
+
+ memcpy(base->Data(), data, len);
+
+ TBlob ret(base->Data(), len, base.Get());
Y_UNUSED(base.Release());
-
- return ret;
-}
-
+
+ return ret;
+}
+
TBlob TBlob::CopySingleThreaded(const void* data, size_t length) {
- return CopyConstruct<TSimpleCounter>(data, length);
-}
-
+ return CopyConstruct<TSimpleCounter>(data, length);
+}
+
TBlob TBlob::Copy(const void* data, size_t length) {
- return CopyConstruct<TAtomicCounter>(data, length);
-}
-
-TBlob TBlob::NoCopy(const void* data, size_t length) {
+ return CopyConstruct<TAtomicCounter>(data, length);
+}
+
+TBlob TBlob::NoCopy(const void* data, size_t length) {
return TBlob(data, length, nullptr);
-}
-
-template <class TCounter>
+}
+
+template <class TCounter>
static inline TBlob ConstructFromMap(const TMemoryMap& map, ui64 offset, size_t length, EMappingMode mode) {
using TBase = TMappedBlobBase<TCounter>;
THolder<TBase> base(new TBase(map, offset, length, mode));
- TBlob ret(base->Data(), base->Length(), base.Get());
+ TBlob ret(base->Data(), base->Length(), base.Get());
Y_UNUSED(base.Release());
-
- return ret;
-}
-
+
+ return ret;
+}
+
template <class TCounter, class T>
static inline TBlob ConstructAsMap(const T& t, EMappingMode mode) {
TMemoryMap::EOpenMode openMode = (mode == EMappingMode::Precharged) ? (TMemoryMap::oRdOnly | TMemoryMap::oPrecharge) : TMemoryMap::oRdOnly;
TMemoryMap map(t, openMode);
- const ui64 toMap = map.Length();
-
- if (toMap > Max<size_t>()) {
- ythrow yexception() << "can not map whole file(length = " << toMap << ")";
- }
-
+ const ui64 toMap = map.Length();
+
+ if (toMap > Max<size_t>()) {
+ ythrow yexception() << "can not map whole file(length = " << toMap << ")";
+ }
+
return ConstructFromMap<TCounter>(map, 0, static_cast<size_t>(toMap), mode);
-}
-
+}
+
TBlob TBlob::FromFileSingleThreaded(const TString& path, EMappingMode mode) {
return ConstructAsMap<TSimpleCounter>(path, mode);
}
@@ -238,20 +238,20 @@ TBlob TBlob::FromFile(const TFile& file, EMappingMode mode) {
TBlob TBlob::FromFileSingleThreaded(const TString& path) {
return ConstructAsMap<TSimpleCounter>(path, EMappingMode::Standard);
-}
-
+}
+
TBlob TBlob::FromFile(const TString& path) {
return ConstructAsMap<TAtomicCounter>(path, EMappingMode::Standard);
-}
-
+}
+
TBlob TBlob::FromFileSingleThreaded(const TFile& file) {
return ConstructAsMap<TSimpleCounter>(file, EMappingMode::Standard);
-}
-
+}
+
TBlob TBlob::FromFile(const TFile& file) {
return ConstructAsMap<TAtomicCounter>(file, EMappingMode::Standard);
-}
-
+}
+
TBlob TBlob::PrechargedFromFileSingleThreaded(const TString& path) {
return ConstructAsMap<TSimpleCounter>(path, EMappingMode::Precharged);
}
@@ -294,36 +294,36 @@ TBlob TBlob::LockedFromMemoryMap(const TMemoryMap& map, ui64 offset, size_t leng
TBlob TBlob::FromMemoryMapSingleThreaded(const TMemoryMap& map, ui64 offset, size_t length) {
return ConstructFromMap<TSimpleCounter>(map, offset, length, EMappingMode::Standard);
-}
-
+}
+
TBlob TBlob::FromMemoryMap(const TMemoryMap& map, ui64 offset, size_t length) {
return ConstructFromMap<TAtomicCounter>(map, offset, length, EMappingMode::Standard);
-}
-
-template <class TCounter>
+}
+
+template <class TCounter>
static inline TBlob ReadFromFile(const TFile& file, ui64 offset, size_t length) {
using TBase = TDynamicBlobBase<TCounter>;
- THolder<TBase> base(new (length) TBase);
-
+ THolder<TBase> base(new (length) TBase);
+
Y_ASSERT(base->Length() == length);
-
- file.Pload(base->Data(), length, offset);
-
- TBlob ret(base->Data(), length, base.Get());
+
+ file.Pload(base->Data(), length, offset);
+
+ TBlob ret(base->Data(), length, base.Get());
Y_UNUSED(base.Release());
-
- return ret;
-}
-
-template <class TCounter>
+
+ return ret;
+}
+
+template <class TCounter>
static inline TBlob ConstructFromFileContent(const TFile& file, ui64 offset, ui64 length) {
if (length > Max<size_t>()) {
ythrow yexception() << "can not read whole file(length = " << length << ")";
}
return ReadFromFile<TCounter>(file, offset, static_cast<size_t>(length));
-}
-
+}
+
TBlob TBlob::FromFileContentSingleThreaded(const TString& path) {
TFile file(path, RdOnly);
return ConstructFromFileContent<TSimpleCounter>(file, 0, file.GetLength());
@@ -343,14 +343,14 @@ TBlob TBlob::FromFileContent(const TFile& file) {
}
TBlob TBlob::FromFileContentSingleThreaded(const TFile& file, ui64 offset, size_t length) {
- return ConstructFromFileContent<TSimpleCounter>(file, offset, length);
-}
-
+ return ConstructFromFileContent<TSimpleCounter>(file, offset, length);
+}
+
TBlob TBlob::FromFileContent(const TFile& file, ui64 offset, size_t length) {
- return ConstructFromFileContent<TAtomicCounter>(file, offset, length);
-}
-
-template <class TCounter>
+ return ConstructFromFileContent<TAtomicCounter>(file, offset, length);
+}
+
+template <class TCounter>
static inline TBlob ConstructFromBuffer(TBuffer& in) {
using TBase = TBufferBlobBase<TCounter>;
THolder<TBase> base(new TBase(in));
@@ -364,23 +364,23 @@ static inline TBlob ConstructFromBuffer(TBuffer& in) {
template <class TCounter>
static inline TBlob ConstructFromStream(IInputStream& in) {
TBuffer buf;
-
- {
- TBufferOutput out(buf);
-
- TransferData(&in, &out);
- }
-
+
+ {
+ TBufferOutput out(buf);
+
+ TransferData(&in, &out);
+ }
+
return ConstructFromBuffer<TCounter>(buf);
-}
-
+}
+
TBlob TBlob::FromStreamSingleThreaded(IInputStream& in) {
return ConstructFromStream<TSimpleCounter>(in);
-}
-
+}
+
TBlob TBlob::FromStream(IInputStream& in) {
return ConstructFromStream<TAtomicCounter>(in);
-}
+}
TBlob TBlob::FromBufferSingleThreaded(TBuffer& in) {
return ConstructFromBuffer<TSimpleCounter>(in);
@@ -389,29 +389,29 @@ TBlob TBlob::FromBufferSingleThreaded(TBuffer& in) {
TBlob TBlob::FromBuffer(TBuffer& in) {
return ConstructFromBuffer<TAtomicCounter>(in);
}
-
+
template <class TCounter, class S>
TBlob ConstructFromString(S&& s) {
using TBase = TStringBlobBase<TCounter>;
auto base = MakeHolder<TBase>(std::forward<S>(s));
-
+
TBlob ret(base->String().data(), base->String().size(), base.Get());
Y_UNUSED(base.Release());
-
- return ret;
-}
-
+
+ return ret;
+}
+
TBlob TBlob::FromStringSingleThreaded(const TString& s) {
- return ConstructFromString<TSimpleCounter>(s);
-}
-
+ return ConstructFromString<TSimpleCounter>(s);
+}
+
TBlob TBlob::FromStringSingleThreaded(TString&& s) {
return ConstructFromString<TSimpleCounter>(std::move(s));
}
TBlob TBlob::FromString(const TString& s) {
- return ConstructFromString<TAtomicCounter>(s);
-}
+ return ConstructFromString<TAtomicCounter>(s);
+}
TBlob TBlob::FromString(TString&& s) {
return ConstructFromString<TAtomicCounter>(std::move(s));
diff --git a/util/memory/blob.h b/util/memory/blob.h
index 4375e6e416..20c02a68df 100644
--- a/util/memory/blob.h
+++ b/util/memory/blob.h
@@ -1,15 +1,15 @@
#pragma once
-
+
#include <util/generic/fwd.h>
#include <util/generic/strbuf.h>
#include <util/generic/utility.h>
#include <util/system/defaults.h>
-
-class TMemoryMap;
+
+class TMemoryMap;
class IInputStream;
class TFile;
class TBuffer;
-
+
enum class EMappingMode {
/// Just mmap a file allowing lazy page loading at access
Standard,
@@ -21,45 +21,45 @@ enum class EMappingMode {
/// @addtogroup BLOBs
/// @{
-class TBlob {
-public:
- class TBase {
- public:
+class TBlob {
+public:
+ class TBase {
+ public:
inline TBase() noexcept = default;
virtual ~TBase() = default;
-
+
virtual void Ref() noexcept = 0;
virtual void UnRef() noexcept = 0;
- };
-
-private:
- struct TStorage {
- const void* Data;
- size_t Length;
- TBase* Base;
-
+ };
+
+private:
+ struct TStorage {
+ const void* Data;
+ size_t Length;
+ TBase* Base;
+
inline TStorage(const void* data, size_t length, TBase* base) noexcept
- : Data(data)
- , Length(length)
- , Base(base)
- {
- }
-
+ : Data(data)
+ , Length(length)
+ , Base(base)
+ {
+ }
+
inline ~TStorage() = default;
-
+
inline void Swap(TStorage& r) noexcept {
- DoSwap(Data, r.Data);
- DoSwap(Length, r.Length);
- DoSwap(Base, r.Base);
- }
- };
-
-public:
+ DoSwap(Data, r.Data);
+ DoSwap(Length, r.Length);
+ DoSwap(Base, r.Base);
+ }
+ };
+
+public:
using value_type = ui8;
using const_reference = const value_type&;
using const_pointer = const value_type*;
using const_iterator = const_pointer;
-
+
/**
* Constructs a null blob (data array points to nullptr).
*/
@@ -67,13 +67,13 @@ public:
: S_(nullptr, 0, nullptr)
{
}
-
+
inline TBlob(const TBlob& r) noexcept
- : S_(r.S_)
- {
- Ref();
- }
-
+ : S_(r.S_)
+ {
+ Ref();
+ }
+
TBlob(TBlob&& r) noexcept
: TBlob()
{
@@ -81,41 +81,41 @@ public:
}
inline TBlob(const void* data, size_t length, TBase* base) noexcept
- : S_(data, length, base)
- {
- Ref();
- }
-
+ : S_(data, length, base)
+ {
+ Ref();
+ }
+
inline ~TBlob() {
- UnRef();
- }
-
+ UnRef();
+ }
+
inline TBlob& operator=(const TBlob& r) noexcept {
- TBlob(r).Swap(*this);
-
- return *this;
- }
-
+ TBlob(r).Swap(*this);
+
+ return *this;
+ }
+
/// Swaps content of two data arrays.
inline void Swap(TBlob& r) noexcept {
- S_.Swap(r.S_);
- }
-
+ S_.Swap(r.S_);
+ }
+
/// Returns a const reference to the data array.
inline const void* Data() const noexcept {
- return S_.Data;
- }
-
+ return S_.Data;
+ }
+
/// Returns the size of the data array in bytes.
inline size_t Length() const noexcept {
- return S_.Length;
- }
-
+ return S_.Length;
+ }
+
/// Checks if the object has an empty data array.
- Y_PURE_FUNCTION inline bool Empty() const noexcept {
- return !Length();
- }
-
+ Y_PURE_FUNCTION inline bool Empty() const noexcept {
+ return !Length();
+ }
+
/// Checks if the blob owns data
Y_PURE_FUNCTION inline bool OwnsData() const noexcept {
return S_.Base != nullptr;
@@ -123,31 +123,31 @@ public:
/// Checks if the object has a data array.
inline bool IsNull() const noexcept {
- return !Data();
- }
-
+ return !Data();
+ }
+
/// Returns a const pointer of char type to the data array.
inline const char* AsCharPtr() const noexcept {
- return (const char*)Data();
- }
-
+ return (const char*)Data();
+ }
+
/// Returns a const pointer of unsigned char type to the data array.
inline const unsigned char* AsUnsignedCharPtr() const noexcept {
- return (const unsigned char*)Data();
- }
-
+ return (const unsigned char*)Data();
+ }
+
inline TStringBuf AsStringBuf() const noexcept {
return TStringBuf(AsCharPtr(), size());
}
/// Drops the data array.
inline void Drop() noexcept {
- TBlob().Swap(*this);
- }
-
- /*
+ TBlob().Swap(*this);
+ }
+
+ /*
* Some stl-like methods
- */
+ */
/// Returns a const reference to the data array.
/// result type is const ui8* which is not consistent with Data method above
@@ -164,42 +164,42 @@ public:
/// Returns the size of the data array in bytes.
inline size_t Size() const noexcept {
- return Length();
- }
-
+ return Length();
+ }
+
/// Standard iterator.
inline const_iterator Begin() const noexcept {
- return AsUnsignedCharPtr();
- }
-
+ return AsUnsignedCharPtr();
+ }
+
/// Standard iterator.
inline const_iterator End() const noexcept {
- return Begin() + Size();
- }
-
+ return Begin() + Size();
+ }
+
inline value_type operator[](size_t n) const noexcept {
- return *(Begin() + n);
- }
-
+ return *(Begin() + n);
+ }
+
/// Shortcut to SubBlob(0, len)
- TBlob SubBlob(size_t len) const;
-
+ TBlob SubBlob(size_t len) const;
+
/// Creates a new object from the provided range [begin, end) of internal data. No memory allocation and no copy.
/// @details Increments the refcounter of the current object
- TBlob SubBlob(size_t begin, size_t end) const;
-
+ TBlob SubBlob(size_t begin, size_t end) const;
+
/// Calls Copy() for the internal data.
- TBlob DeepCopy() const;
-
+ TBlob DeepCopy() const;
+
/// Creates a new blob with a single-threaded (non atomic) refcounter. Dynamically allocates memory and copies the data content.
- static TBlob CopySingleThreaded(const void* data, size_t length);
-
+ static TBlob CopySingleThreaded(const void* data, size_t length);
+
/// Creates a new blob with a multi-threaded (atomic) refcounter. Dynamically allocates memory and copies the data content.
- static TBlob Copy(const void* data, size_t length);
-
+ static TBlob Copy(const void* data, size_t length);
+
/// Creates a blob which doesn't own data. No refcounter, no memory allocation, no data copy.
- static TBlob NoCopy(const void* data, size_t length);
-
+ static TBlob NoCopy(const void* data, size_t length);
+
/// Creates a blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
static TBlob FromFileSingleThreaded(const TString& path, EMappingMode);
@@ -214,16 +214,16 @@ public:
/// Creates a blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
static TBlob FromFileSingleThreaded(const TString& path);
-
+
/// Creates a blob with a multi-threaded (atomic) refcounter. It maps the file on the path as data.
static TBlob FromFile(const TString& path);
-
+
/// Creates a blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
static TBlob FromFileSingleThreaded(const TFile& file);
-
+
/// Creates a blob with a multi-threaded (atomic) refcounter. It maps the file on the path as data.
static TBlob FromFile(const TFile& file);
-
+
// TODO: drop Precharged* functions.
/// Creates a precharged blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
@@ -257,11 +257,11 @@ public:
static TBlob LockedFromMemoryMap(const TMemoryMap& map, ui64 offset, size_t length);
/// Creates a blob with a single-threaded (non atomic) refcounter from the mapped memory.
- static TBlob FromMemoryMapSingleThreaded(const TMemoryMap& map, ui64 offset, size_t length);
-
+ static TBlob FromMemoryMapSingleThreaded(const TMemoryMap& map, ui64 offset, size_t length);
+
/// Creates a blob with a multi-threaded (atomic) refcounter from the mapped memory.
- static TBlob FromMemoryMap(const TMemoryMap& map, ui64 offset, size_t length);
-
+ static TBlob FromMemoryMap(const TMemoryMap& map, ui64 offset, size_t length);
+
/// Creates a blob with a single-threaded (non atomic) refcounter. Dynamically allocates memory and copies data from the file on the path using pread().
static TBlob FromFileContentSingleThreaded(const TString& path);
@@ -269,58 +269,58 @@ public:
static TBlob FromFileContent(const TString& path);
/// Creates a blob with a single-threaded (non atomic) refcounter. Dynamically allocates memory and copies data from the file using pread().
- static TBlob FromFileContentSingleThreaded(const TFile& file);
+ static TBlob FromFileContentSingleThreaded(const TFile& file);
/// Creates a blob with a multi-threaded (atomic) refcounter. Dynamically allocates memory and copies data from the file using pread().
- static TBlob FromFileContent(const TFile& file);
+ static TBlob FromFileContent(const TFile& file);
/// Creates a blob with a single-threaded (non atomic) refcounter. Dynamically allocates memory and copies data from the provided range of the file content using pread().
- static TBlob FromFileContentSingleThreaded(const TFile& file, ui64 offset, size_t length);
-
+ static TBlob FromFileContentSingleThreaded(const TFile& file, ui64 offset, size_t length);
+
/// Creates a blob with a multi-threaded (atomic) refcounter. Dynamically allocates memory and copies data from the provided range of the file content using pread().
- static TBlob FromFileContent(const TFile& file, ui64 offset, size_t length);
-
+ static TBlob FromFileContent(const TFile& file, ui64 offset, size_t length);
+
/// Creates a blob from the stream content with a single-threaded (non atomic) refcounter.
static TBlob FromStreamSingleThreaded(IInputStream& in);
-
+
/// Creates a blob from the stream content with a multi-threaded (atomic) refcounter.
static TBlob FromStream(IInputStream& in);
-
+
/// Creates a blob with a single-threaded (non atomic) refcounter. No memory allocation, no content copy.
/// @details The input object becomes empty.
- static TBlob FromBufferSingleThreaded(TBuffer& in);
+ static TBlob FromBufferSingleThreaded(TBuffer& in);
/// Creates a blob with a multi-threaded (atomic) refcounter. No memory allocation, no content copy.
/// @details The input object becomes empty.
- static TBlob FromBuffer(TBuffer& in);
+ static TBlob FromBuffer(TBuffer& in);
/// Creates a blob from TString with a single-threaded (non atomic) refcounter.
static TBlob FromStringSingleThreaded(const TString& s);
-
+
/// Creates a blob from TString with a single-threaded (non atomic) refcounter. Doesn't copy its content.
static TBlob FromStringSingleThreaded(TString&& s);
/// Creates a blob from TString with a multi-threaded (atomic) refcounter.
static TBlob FromString(const TString& s);
-
+
/// Creates a blob from TString with a multi-threaded (atomic) refcounter. Doesn't copy its content.
static TBlob FromString(TString&& s);
-private:
+private:
inline void Ref() noexcept {
if (S_.Base) {
S_.Base->Ref();
}
- }
-
+ }
+
inline void UnRef() noexcept {
if (S_.Base) {
S_.Base->UnRef();
}
- }
-
-private:
- TStorage S_;
-};
-
+ }
+
+private:
+ TStorage S_;
+};
+
/// @}
diff --git a/util/memory/blob_ut.cpp b/util/memory/blob_ut.cpp
index 84882a7a9d..023f9a0487 100644
--- a/util/memory/blob_ut.cpp
+++ b/util/memory/blob_ut.cpp
@@ -1,5 +1,5 @@
-#include "blob.h"
-
+#include "blob.h"
+
#include <library/cpp/testing/unittest/registar.h>
#include <util/system/tempfile.h>
@@ -8,72 +8,72 @@
#include <util/stream/file.h>
#include <util/generic/buffer.h>
#include <util/generic/array_ref.h>
-
-Y_UNIT_TEST_SUITE(TBlobTest) {
- Y_UNIT_TEST(TestSubBlob) {
- TBlob child;
- const char* p = nullptr;
- {
- TBlob parent = TBlob::CopySingleThreaded("0123456789", 10);
- UNIT_ASSERT_EQUAL(parent.Length(), 10);
- p = parent.AsCharPtr();
- UNIT_ASSERT_EQUAL(memcmp(p, "0123456789", 10), 0);
- child = parent.SubBlob(2, 5);
- } // Don't worry about parent
+Y_UNIT_TEST_SUITE(TBlobTest) {
+ Y_UNIT_TEST(TestSubBlob) {
+ TBlob child;
+ const char* p = nullptr;
+
+ {
+ TBlob parent = TBlob::CopySingleThreaded("0123456789", 10);
+ UNIT_ASSERT_EQUAL(parent.Length(), 10);
+ p = parent.AsCharPtr();
+ UNIT_ASSERT_EQUAL(memcmp(p, "0123456789", 10), 0);
+ child = parent.SubBlob(2, 5);
+ } // Don't worry about parent
+
+ UNIT_ASSERT_EQUAL(child.Length(), 3);
+ UNIT_ASSERT_EQUAL(memcmp(child.AsCharPtr(), "234", 3), 0);
+ UNIT_ASSERT_EQUAL(p + 2, child.AsCharPtr());
+ }
+
+ Y_UNIT_TEST(TestFromStream) {
+ TString s("sjklfgsdyutfuyas54fa78s5f89a6df790asdf7");
+ TMemoryInput mi(s.data(), s.size());
+ TBlob b = TBlob::FromStreamSingleThreaded(mi);
- UNIT_ASSERT_EQUAL(child.Length(), 3);
- UNIT_ASSERT_EQUAL(memcmp(child.AsCharPtr(), "234", 3), 0);
- UNIT_ASSERT_EQUAL(p + 2, child.AsCharPtr());
- }
+ UNIT_ASSERT_EQUAL(TString((const char*)b.Data(), b.Length()), s);
+ }
- Y_UNIT_TEST(TestFromStream) {
- TString s("sjklfgsdyutfuyas54fa78s5f89a6df790asdf7");
- TMemoryInput mi(s.data(), s.size());
- TBlob b = TBlob::FromStreamSingleThreaded(mi);
-
- UNIT_ASSERT_EQUAL(TString((const char*)b.Data(), b.Length()), s);
- }
-
- Y_UNIT_TEST(TestFromString) {
- TString s("dsfkjhgsadftusadtf");
- TBlob b(TBlob::FromString(s));
+ Y_UNIT_TEST(TestFromString) {
+ TString s("dsfkjhgsadftusadtf");
+ TBlob b(TBlob::FromString(s));
- UNIT_ASSERT_EQUAL(TString((const char*)b.Data(), b.Size()), s);
- const auto expectedRef = TArrayRef<const ui8>{(ui8*)s.data(), s.size()};
- UNIT_ASSERT_EQUAL(TArrayRef<const ui8>{b}, expectedRef);
- }
+ UNIT_ASSERT_EQUAL(TString((const char*)b.Data(), b.Size()), s);
+ const auto expectedRef = TArrayRef<const ui8>{(ui8*)s.data(), s.size()};
+ UNIT_ASSERT_EQUAL(TArrayRef<const ui8>{b}, expectedRef);
+ }
- Y_UNIT_TEST(TestFromBuffer) {
- const size_t sz = 1234u;
- TBuffer buf;
- buf.Resize(sz);
- UNIT_ASSERT_EQUAL(buf.Size(), sz);
- TBlob b = TBlob::FromBuffer(buf);
- UNIT_ASSERT_EQUAL(buf.Size(), 0u);
- UNIT_ASSERT_EQUAL(b.Size(), sz);
- }
+ Y_UNIT_TEST(TestFromBuffer) {
+ const size_t sz = 1234u;
+ TBuffer buf;
+ buf.Resize(sz);
+ UNIT_ASSERT_EQUAL(buf.Size(), sz);
+ TBlob b = TBlob::FromBuffer(buf);
+ UNIT_ASSERT_EQUAL(buf.Size(), 0u);
+ UNIT_ASSERT_EQUAL(b.Size(), sz);
+ }
- Y_UNIT_TEST(TestFromFile) {
- TString path = "testfile";
+ Y_UNIT_TEST(TestFromFile) {
+ TString path = "testfile";
- TOFStream stream(path);
- stream.Write("1234", 4);
- stream.Finish();
+ TOFStream stream(path);
+ stream.Write("1234", 4);
+ stream.Finish();
- auto testMode = [](TBlob blob) {
- UNIT_ASSERT_EQUAL(blob.Size(), 4);
- UNIT_ASSERT_EQUAL(TStringBuf(static_cast<const char*>(blob.Data()), 4), "1234");
- };
+ auto testMode = [](TBlob blob) {
+ UNIT_ASSERT_EQUAL(blob.Size(), 4);
+ UNIT_ASSERT_EQUAL(TStringBuf(static_cast<const char*>(blob.Data()), 4), "1234");
+ };
- testMode(TBlob::FromFile(path));
- testMode(TBlob::PrechargedFromFile(path));
- testMode(TBlob::LockedFromFile(path));
- }
+ testMode(TBlob::FromFile(path));
+ testMode(TBlob::PrechargedFromFile(path));
+ testMode(TBlob::LockedFromFile(path));
+ }
- Y_UNIT_TEST(TestEmptyLockedFiles) {
- TString path = MakeTempName();
- TFsPath(path).Touch();
- TBlob::LockedFromFile(path);
- }
-};
+ Y_UNIT_TEST(TestEmptyLockedFiles) {
+ TString path = MakeTempName();
+ TFsPath(path).Touch();
+ TBlob::LockedFromFile(path);
+ }
+};
diff --git a/util/memory/mmapalloc.cpp b/util/memory/mmapalloc.cpp
index 59e4ef8012..ec618cc808 100644
--- a/util/memory/mmapalloc.cpp
+++ b/util/memory/mmapalloc.cpp
@@ -1,33 +1,33 @@
-#include "alloc.h"
-#include "mmapalloc.h"
-
-#include <util/system/filemap.h>
-#include <util/generic/singleton.h>
-
-namespace {
- class TMmapAllocator: public IAllocator {
- public:
+#include "alloc.h"
+#include "mmapalloc.h"
+
+#include <util/system/filemap.h>
+#include <util/generic/singleton.h>
+
+namespace {
+ class TMmapAllocator: public IAllocator {
+ public:
TBlock Allocate(size_t len) override {
- TMappedAllocation m(len + sizeof(TMappedAllocation));
- TMappedAllocation* real = (TMappedAllocation*)m.Data();
-
- (new (real) TMappedAllocation(0))->swap(m);
-
- TBlock ret = {real + 1, len};
-
- return ret;
- }
-
+ TMappedAllocation m(len + sizeof(TMappedAllocation));
+ TMappedAllocation* real = (TMappedAllocation*)m.Data();
+
+ (new (real) TMappedAllocation(0))->swap(m);
+
+ TBlock ret = {real + 1, len};
+
+ return ret;
+ }
+
void Release(const TBlock& block) override {
- TMappedAllocation tmp(0);
- TMappedAllocation* real = ((TMappedAllocation*)block.Data) - 1;
-
- real->swap(tmp);
- real->~TMappedAllocation();
- }
- };
-}
-
-IAllocator* MmapAllocator() {
- return SingletonWithPriority<TMmapAllocator, 0>();
-}
+ TMappedAllocation tmp(0);
+ TMappedAllocation* real = ((TMappedAllocation*)block.Data) - 1;
+
+ real->swap(tmp);
+ real->~TMappedAllocation();
+ }
+ };
+}
+
+IAllocator* MmapAllocator() {
+ return SingletonWithPriority<TMmapAllocator, 0>();
+}
diff --git a/util/memory/mmapalloc.h b/util/memory/mmapalloc.h
index d1410795c8..06002e58fc 100644
--- a/util/memory/mmapalloc.h
+++ b/util/memory/mmapalloc.h
@@ -1,8 +1,8 @@
#pragma once
-
-class IAllocator;
-
-/*
- * return anonymous memory based allocator
- */
-IAllocator* MmapAllocator();
+
+class IAllocator;
+
+/*
+ * return anonymous memory based allocator
+ */
+IAllocator* MmapAllocator();
diff --git a/util/memory/pool.cpp b/util/memory/pool.cpp
index b3144aefc3..9a011f0e4f 100644
--- a/util/memory/pool.cpp
+++ b/util/memory/pool.cpp
@@ -1,55 +1,55 @@
-#include "pool.h"
-
+#include "pool.h"
+
TMemoryPool::IGrowPolicy* TMemoryPool::TLinearGrow::Instance() noexcept {
- return SingletonWithPriority<TLinearGrow, 0>();
-}
-
+ return SingletonWithPriority<TLinearGrow, 0>();
+}
+
TMemoryPool::IGrowPolicy* TMemoryPool::TExpGrow::Instance() noexcept {
- return SingletonWithPriority<TExpGrow, 0>();
-}
-
-void TMemoryPool::AddChunk(size_t hint) {
- const size_t dataLen = Max(BlockSize_, hint);
+ return SingletonWithPriority<TExpGrow, 0>();
+}
+
+void TMemoryPool::AddChunk(size_t hint) {
+ const size_t dataLen = Max(BlockSize_, hint);
size_t allocSize = dataLen + sizeof(TChunk);
if (Options_.RoundUpToNextPowerOfTwo) {
allocSize = FastClp2(allocSize);
}
TBlock nb = Alloc_->Allocate(allocSize);
-
+
// Add previous chunk's stats
if (Current_ != &Empty_) {
MemoryAllocatedBeforeCurrent_ += Current_->Used();
MemoryWasteBeforeCurrent_ += Current_->Left();
}
- BlockSize_ = GrowPolicy_->Next(dataLen);
- Current_ = new (nb.Data) TChunk(nb.Len - sizeof(TChunk));
- Chunks_.PushBack(Current_);
-}
-
-void TMemoryPool::DoClear(bool keepfirst) noexcept {
- while (!Chunks_.Empty()) {
- TChunk* c = Chunks_.PopBack();
-
- if (keepfirst && Chunks_.Empty()) {
- c->ResetChunk();
- Chunks_.PushBack(c);
- Current_ = c;
- BlockSize_ = c->BlockLength() - sizeof(TChunk);
- MemoryAllocatedBeforeCurrent_ = 0;
+ BlockSize_ = GrowPolicy_->Next(dataLen);
+ Current_ = new (nb.Data) TChunk(nb.Len - sizeof(TChunk));
+ Chunks_.PushBack(Current_);
+}
+
+void TMemoryPool::DoClear(bool keepfirst) noexcept {
+ while (!Chunks_.Empty()) {
+ TChunk* c = Chunks_.PopBack();
+
+ if (keepfirst && Chunks_.Empty()) {
+ c->ResetChunk();
+ Chunks_.PushBack(c);
+ Current_ = c;
+ BlockSize_ = c->BlockLength() - sizeof(TChunk);
+ MemoryAllocatedBeforeCurrent_ = 0;
MemoryWasteBeforeCurrent_ = 0;
- return;
- }
-
- TBlock b = {c, c->BlockLength()};
-
- c->~TChunk();
- Alloc_->Release(b);
- }
-
- Current_ = &Empty_;
- BlockSize_ = Origin_;
+ return;
+ }
+
+ TBlock b = {c, c->BlockLength()};
+
+ c->~TChunk();
+ Alloc_->Release(b);
+ }
+
+ Current_ = &Empty_;
+ BlockSize_ = Origin_;
MemoryAllocatedBeforeCurrent_ = 0;
MemoryWasteBeforeCurrent_ = 0;
-}
+}
diff --git a/util/memory/pool.h b/util/memory/pool.h
index 8802f4fb1b..13c8b6b9ed 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;
- }
- return arr;
- }
+ for (T *ptr = arr, *end = arr + count; ptr != end; ++ptr) {
+ new (ptr) T;
+ }
+
+ 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.
diff --git a/util/memory/pool_ut.cpp b/util/memory/pool_ut.cpp
index 2d0bfa011d..1158a8ca42 100644
--- a/util/memory/pool_ut.cpp
+++ b/util/memory/pool_ut.cpp
@@ -1,55 +1,55 @@
-#include "pool.h"
-
+#include "pool.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <util/stream/output.h>
-
+
class TCheckedAllocator: public TDefaultAllocator {
public:
inline TCheckedAllocator()
: Alloced_(0)
, Released_(0)
, Allocs_(0)
- , Frees_(0)
- {
+ , Frees_(0)
+ {
}
-
+
TBlock Allocate(size_t len) override {
Check();
-
+
Alloced_ += len;
++Allocs_;
-
+
return TDefaultAllocator::Allocate(len);
}
-
+
void Release(const TBlock& block) override {
Released_ += block.Len;
++Frees_;
-
+
Check();
-
+
TDefaultAllocator::Release(block);
}
-
+
inline void CheckAtEnd() {
UNIT_ASSERT_EQUAL(Alloced_, Released_);
UNIT_ASSERT_EQUAL(Allocs_, Frees_);
}
-
+
private:
inline void Check() {
UNIT_ASSERT(Alloced_ >= Released_);
UNIT_ASSERT(Allocs_ >= Frees_);
}
-
+
private:
size_t Alloced_;
size_t Released_;
size_t Allocs_;
size_t Frees_;
};
-
+
class TErrorOnCopy {
public:
TErrorOnCopy() = default;
@@ -85,46 +85,46 @@ class TMemPoolTest: public TTestBase {
UNIT_TEST(TestMoveAlloc)
UNIT_TEST(TestRoundUpToNextPowerOfTwoOption)
UNIT_TEST_SUITE_END();
-
+
private:
inline void TestMemPool() {
TCheckedAllocator alloc;
- {
- TMemoryPool pool(123, TMemoryPool::TExpGrow::Instance(), &alloc);
-
- for (size_t i = 0; i < 1000; ++i) {
- UNIT_ASSERT(pool.Allocate(i));
- }
- }
-
- alloc.CheckAtEnd();
-
- {
- TMemoryPool pool(150, TMemoryPool::TExpGrow::Instance(), &alloc);
-
- pool.Allocate(8);
-
- size_t memavail = pool.Available();
- size_t memwaste = pool.MemoryWaste();
- size_t memalloc = pool.MemoryAllocated();
-
- for (size_t i = 0; i < 1000; ++i) {
- void* m = pool.Allocate(i);
- UNIT_ASSERT(m);
- memset(m, 0, i);
- }
-
- pool.ClearKeepFirstChunk();
-
- UNIT_ASSERT_VALUES_EQUAL(memalloc - 8, pool.MemoryAllocated());
- UNIT_ASSERT_VALUES_EQUAL(memwaste + 8, pool.MemoryWaste());
- UNIT_ASSERT_VALUES_EQUAL(memavail + 8, pool.Available());
-
- for (size_t i = 0; i < 1000; ++i) {
- void* m = pool.Allocate(i);
- UNIT_ASSERT(m);
- memset(m, 0, i);
+ {
+ TMemoryPool pool(123, TMemoryPool::TExpGrow::Instance(), &alloc);
+
+ for (size_t i = 0; i < 1000; ++i) {
+ UNIT_ASSERT(pool.Allocate(i));
+ }
+ }
+
+ alloc.CheckAtEnd();
+
+ {
+ TMemoryPool pool(150, TMemoryPool::TExpGrow::Instance(), &alloc);
+
+ pool.Allocate(8);
+
+ size_t memavail = pool.Available();
+ size_t memwaste = pool.MemoryWaste();
+ size_t memalloc = pool.MemoryAllocated();
+
+ for (size_t i = 0; i < 1000; ++i) {
+ void* m = pool.Allocate(i);
+ UNIT_ASSERT(m);
+ memset(m, 0, i);
+ }
+
+ pool.ClearKeepFirstChunk();
+
+ UNIT_ASSERT_VALUES_EQUAL(memalloc - 8, pool.MemoryAllocated());
+ UNIT_ASSERT_VALUES_EQUAL(memwaste + 8, pool.MemoryWaste());
+ UNIT_ASSERT_VALUES_EQUAL(memavail + 8, pool.Available());
+
+ for (size_t i = 0; i < 1000; ++i) {
+ void* m = pool.Allocate(i);
+ UNIT_ASSERT(m);
+ memset(m, 0, i);
}
pool.Clear();
@@ -132,28 +132,28 @@ private:
UNIT_ASSERT_VALUES_EQUAL(0, pool.MemoryAllocated());
UNIT_ASSERT_VALUES_EQUAL(0, pool.MemoryWaste());
UNIT_ASSERT_VALUES_EQUAL(0, pool.Available());
- }
+ }
- alloc.CheckAtEnd();
+ alloc.CheckAtEnd();
struct TConstructorTest {
int ConstructorType;
- TConstructorTest()
- : ConstructorType(1)
- {
- }
- TConstructorTest(int)
- : ConstructorType(2)
- {
- }
+ TConstructorTest()
+ : ConstructorType(1)
+ {
+ }
+ TConstructorTest(int)
+ : ConstructorType(2)
+ {
+ }
TConstructorTest(const TString&, const TString&)
- : ConstructorType(3)
- {
- }
+ : ConstructorType(3)
+ {
+ }
TConstructorTest(TString&&, TString&&)
- : ConstructorType(4)
- {
- }
+ : ConstructorType(4)
+ {
+ }
};
{
@@ -167,7 +167,7 @@ private:
}
alloc.CheckAtEnd();
- }
+ }
inline void TestAlign() {
TMemoryPool pool(1);
@@ -232,7 +232,7 @@ private:
elems.reserve(1);
elems.emplace_back();
elems.resize(100);
- }
+ }
void TestMoveAlloc() {
CheckMoveAlloc<TNoMove>();
@@ -243,7 +243,7 @@ private:
void TestRoundUpToNextPowerOfTwoOption() {
const size_t MEMORY_POOL_BLOCK_SIZE = (1024 - 16) * 4096 - 16 - 16 - 32;
- class TFixedBlockSizeMemoryPoolPolicy final: public TMemoryPool::IGrowPolicy {
+ class TFixedBlockSizeMemoryPoolPolicy final: public TMemoryPool::IGrowPolicy {
public:
size_t Next(size_t /*prev*/) const noexcept override {
return MEMORY_POOL_BLOCK_SIZE;
@@ -251,7 +251,7 @@ private:
};
TFixedBlockSizeMemoryPoolPolicy allocationPolicy;
- class TTestAllocator final: public TDefaultAllocator {
+ class TTestAllocator final: public TDefaultAllocator {
public:
TBlock Allocate(size_t len) override {
Size_ += len;
@@ -280,6 +280,6 @@ private:
pool.Allocate(1);
UNIT_ASSERT_VALUES_EQUAL(2 * EXPECTED_ALLOCATION_SIZE, allocator.GetSize());
}
-};
-
-UNIT_TEST_SUITE_REGISTRATION(TMemPoolTest);
+};
+
+UNIT_TEST_SUITE_REGISTRATION(TMemPoolTest);
diff --git a/util/memory/segmented_string_pool.cpp b/util/memory/segmented_string_pool.cpp
index e2a561fcb5..9cfe7af8a4 100644
--- a/util/memory/segmented_string_pool.cpp
+++ b/util/memory/segmented_string_pool.cpp
@@ -1 +1 @@
-#include "segmented_string_pool.h"
+#include "segmented_string_pool.h"
diff --git a/util/memory/segmented_string_pool.h b/util/memory/segmented_string_pool.h
index 2208ceed6d..a40aa408f5 100644
--- a/util/memory/segmented_string_pool.h
+++ b/util/memory/segmented_string_pool.h
@@ -1,39 +1,39 @@
#pragma once
#include <util/system/align.h>
-#include <util/system/yassert.h>
-#include <util/system/defaults.h>
+#include <util/system/yassert.h>
+#include <util/system/defaults.h>
#include <util/generic/noncopyable.h>
-#include <util/generic/vector.h>
+#include <util/generic/vector.h>
#include <util/generic/strbuf.h>
-
+
#include <memory>
-#include <cstdio>
-#include <cstdlib>
-
+#include <cstdio>
+#include <cstdlib>
+
/*
* Non-reallocated storage for the objects of POD type
*/
template <class T, class Alloc = std::allocator<T>>
-class segmented_pool: TNonCopyable {
+class segmented_pool: TNonCopyable {
protected:
- Alloc seg_allocator;
+ Alloc seg_allocator;
struct seg_inf {
- T* data; // allocated chunk
+ T* data; // allocated chunk
size_t _size; // size of allocated chunk in sizeof(T)-units
size_t freepos; // offset to free chunk's memory in bytes
- seg_inf()
+ seg_inf()
: data(nullptr)
- , _size(0)
- , freepos(0)
- {
- }
+ , _size(0)
+ , freepos(0)
+ {
+ }
seg_inf(T* d, size_t sz)
- : data(d)
- , _size(sz)
- , freepos(0)
- {
- }
+ : data(d)
+ , _size(sz)
+ , freepos(0)
+ {
+ }
};
using seg_container = TVector<seg_inf>;
using seg_iterator = typename seg_container::iterator;
@@ -53,20 +53,20 @@ protected:
if (curseg == segs.end() || curseg->_size < last_free) {
segs.push_back(seg_inf(seg_allocator.allocate(last_free), last_free));
if (Y_UNLIKELY(Name))
- printf("Pool \"%s\" was increased by %" PRISZT " bytes to %" PRISZT " Mb.\n", Name, last_free * sizeof(T), capacity() / 0x100000);
+ printf("Pool \"%s\" was increased by %" PRISZT " bytes to %" PRISZT " Mb.\n", Name, last_free * sizeof(T), capacity() / 0x100000);
curseg = segs.end() - 1;
}
Y_ASSERT(curseg->freepos == 0);
Y_ASSERT(curseg->_size >= last_free);
}
}
-
+
public:
explicit segmented_pool(size_t segsz, const char* name = nullptr)
- : segment_size(segsz)
- , last_free(0)
- , last_ins_size(0)
- , Name(name)
+ : segment_size(segsz)
+ , last_free(0)
+ , last_ins_size(0)
+ , Name(name)
{
curseg = segs.begin();
}
@@ -74,23 +74,23 @@ public:
clear();
}
/* src - array of objects, len - count of elements in array */
- T* append(const T* src, size_t len) {
+ T* append(const T* src, size_t len) {
check_capacity(len);
- ui8* rv = (ui8*)curseg->data + curseg->freepos;
+ ui8* rv = (ui8*)curseg->data + curseg->freepos;
last_ins_size = sizeof(T) * len;
if (src)
memcpy(rv, src, last_ins_size);
curseg->freepos += last_ins_size, last_free -= len;
return (T*)rv;
}
- T* append() {
+ T* append() {
T* obj = get_raw();
- new (obj) T();
+ new (obj) T();
return obj;
}
- T* get_raw() { // append(0, 1)
+ T* get_raw() { // append(0, 1)
check_capacity(1);
- ui8* rv = (ui8*)curseg->data + curseg->freepos;
+ ui8* rv = (ui8*)curseg->data + curseg->freepos;
last_ins_size = sizeof(T);
curseg->freepos += last_ins_size, last_free -= 1;
return (T*)rv;
@@ -100,7 +100,7 @@ public:
}
bool contains(const T* ptr) const {
for (seg_const_iterator i = segs.begin(), ie = segs.end(); i != ie; ++i)
- if ((char*)ptr >= (char*)i->data && (char*)ptr < (char*)i->data + i->freepos)
+ if ((char*)ptr >= (char*)i->data && (char*)ptr < (char*)i->data + i->freepos)
return true;
return false;
}
@@ -146,10 +146,10 @@ public:
}
};
-class segmented_string_pool: public segmented_pool<char> {
+class segmented_string_pool: public segmented_pool<char> {
private:
using _Base = segmented_pool<char>;
-
+
public:
segmented_string_pool()
: segmented_string_pool(1024 * 1024)
@@ -157,14 +157,14 @@ public:
}
explicit segmented_string_pool(size_t segsz)
- : _Base(segsz)
- {
- }
- char* append(const char* src) {
+ : _Base(segsz)
+ {
+ }
+ char* append(const char* src) {
Y_ASSERT(src);
return _Base::append(src, strlen(src) + 1);
}
- char* append(const char* src, size_t len) {
+ char* append(const char* src, size_t len) {
char* rv = _Base::append(nullptr, len + 1);
if (src)
memcpy(rv, src, len);
@@ -185,7 +185,7 @@ public:
};
template <typename T, typename C>
-inline T* pool_push(segmented_pool<C>& pool, const T* v) {
+inline T* pool_push(segmented_pool<C>& pool, const T* v) {
static_assert(sizeof(C) == 1, "only char type supported");
size_t len = SizeOf(v);
C* buf = pool.append(nullptr, AlignUp(len));
diff --git a/util/memory/segpool_alloc.cpp b/util/memory/segpool_alloc.cpp
index 1893487aa6..2b3a29fe51 100644
--- a/util/memory/segpool_alloc.cpp
+++ b/util/memory/segpool_alloc.cpp
@@ -1 +1 @@
-#include "segpool_alloc.h"
+#include "segpool_alloc.h"
diff --git a/util/memory/segpool_alloc.h b/util/memory/segpool_alloc.h
index 7917f07407..1a83b7a543 100644
--- a/util/memory/segpool_alloc.h
+++ b/util/memory/segpool_alloc.h
@@ -42,28 +42,28 @@ struct segpool_alloc {
#ifndef NDEBUG
ui64 pool_count, malloc_count, pool_free_count, malloc_free_count;
#endif
- segpool_alloc()
+ segpool_alloc()
: pool(nullptr)
- {
+ {
Y_IF_DEBUG(pool_count = malloc_count = pool_free_count = malloc_free_count = 0);
}
segpool_alloc(pool_type* p)
- : pool(p)
- {
+ : pool(p)
+ {
Y_IF_DEBUG(pool_count = malloc_count = pool_free_count = malloc_free_count = 0);
}
segpool_alloc(const segpool_alloc& a)
- : pool(a.pool)
- {
+ : pool(a.pool)
+ {
Y_IF_DEBUG(pool_count = malloc_count = pool_free_count = malloc_free_count = 0);
}
template <class _Tp1>
segpool_alloc(const segpool_alloc<_Tp1>& a)
- : pool(a.pool)
- {
+ : pool(a.pool)
+ {
Y_IF_DEBUG(pool_count = malloc_count = pool_free_count = malloc_free_count = 0);
- }
- _Tp* allocate(size_t __n) {
+ }
+ _Tp* allocate(size_t __n) {
if (!pool) {
_Tp* data = (_Tp*)malloc(__n * sizeof(_Tp));
Y_IF_DEBUG(if (data) malloc_count++);
@@ -83,35 +83,35 @@ struct segpool_alloc {
}
}
~segpool_alloc() {
- //assert(pool_count == pool_free_count && malloc_count == malloc_free_count); <- uncomment when swap() problem is solved
+ //assert(pool_count == pool_free_count && malloc_count == malloc_free_count); <- uncomment when swap() problem is solved
//printf("in ~segpool_alloc: size = %u, pool_count = %" PRId64 ", malloc_count = %" PRId64 ", pool_free_count = %" PRId64 ", malloc_free_count = %" PRId64 "\n",
// sizeof(_Tp), pool_count, malloc_count, pool_free_count, malloc_free_count);
- //fflush(stdout);
+ //fflush(stdout);
}
- template <class _Tp1>
- struct rebind {
+ template <class _Tp1>
+ struct rebind {
using other = segpool_alloc<_Tp1>;
};
size_type max_size() const {
return size_type(-1) / sizeof(_Tp);
}
- void construct(pointer __p, const _Tp& __val) {
- new (__p) _Tp(__val);
- }
- void destroy(pointer __p) {
- (void)__p; /* Make MSVC happy. */
- __p->~_Tp();
- }
+ void construct(pointer __p, const _Tp& __val) {
+ new (__p) _Tp(__val);
+ }
+ void destroy(pointer __p) {
+ (void)__p; /* Make MSVC happy. */
+ __p->~_Tp();
+ }
};
-
+
template <class _Tp>
-inline bool operator==(const segpool_alloc<_Tp>& a1, const segpool_alloc<_Tp>& a2) {
- return a1.pool == a2.pool;
+inline bool operator==(const segpool_alloc<_Tp>& a1, const segpool_alloc<_Tp>& a2) {
+ return a1.pool == a2.pool;
}
template <class _Tp>
-inline bool operator!=(const segpool_alloc<_Tp>& a1, const segpool_alloc<_Tp>& a2) {
- return a1.pool != a2.pool;
+inline bool operator!=(const segpool_alloc<_Tp>& a1, const segpool_alloc<_Tp>& a2) {
+ return a1.pool != a2.pool;
}
// Any type since it is supposed to be rebound anyway.
diff --git a/util/memory/smallobj.cpp b/util/memory/smallobj.cpp
index 82bd9e29bd..4605c08720 100644
--- a/util/memory/smallobj.cpp
+++ b/util/memory/smallobj.cpp
@@ -1 +1 @@
-#include "smallobj.h"
+#include "smallobj.h"
diff --git a/util/memory/smallobj.h b/util/memory/smallobj.h
index ef6814bbb3..63de666bae 100644
--- a/util/memory/smallobj.h
+++ b/util/memory/smallobj.h
@@ -1,42 +1,42 @@
#pragma once
-
-#include "pool.h"
-#include "alloc.h"
-
+
+#include "pool.h"
+#include "alloc.h"
+
#include <util/generic/utility.h>
-#include <util/generic/intrlist.h>
-
-class TFixedSizeAllocator {
- struct TAlloc: public TIntrusiveSListItem<TAlloc> {
+#include <util/generic/intrlist.h>
+
+class TFixedSizeAllocator {
+ struct TAlloc: public TIntrusiveSListItem<TAlloc> {
inline void* ToPointer() noexcept {
- return this;
- }
-
+ return this;
+ }
+
static inline TAlloc* FromPointer(void* ptr) noexcept {
- return (TAlloc*)ptr;
- }
-
+ return (TAlloc*)ptr;
+ }
+
static constexpr size_t EntitySize(size_t alloc) noexcept {
- return Max(sizeof(TAlloc), alloc);
- }
-
+ return Max(sizeof(TAlloc), alloc);
+ }
+
static constexpr size_t EntityAlign(size_t align) noexcept {
return Max(alignof(TAlloc), align);
}
static inline TAlloc* Construct(void* ptr) noexcept {
- return (TAlloc*)ptr;
- }
- };
-
-public:
+ return (TAlloc*)ptr;
+ }
+ };
+
+public:
using IGrowPolicy = TMemoryPool::IGrowPolicy;
-
+
TFixedSizeAllocator(size_t allocSize, IAllocator* alloc)
: TFixedSizeAllocator(allocSize, alignof(TAlloc), TMemoryPool::TExpGrow::Instance(), alloc)
- {
- }
-
+ {
+ }
+
TFixedSizeAllocator(size_t allocSize, size_t alignSize, IAllocator* alloc)
: TFixedSizeAllocator(allocSize, alignSize, TMemoryPool::TExpGrow::Instance(), alloc)
{
@@ -48,94 +48,94 @@ public:
}
TFixedSizeAllocator(size_t allocSize, size_t alignSize, IGrowPolicy* grow, IAllocator* alloc)
- : Pool_(allocSize, grow, alloc)
+ : Pool_(allocSize, grow, alloc)
, AlignSize_(TAlloc::EntityAlign(alignSize))
, AllocSize_(TAlloc::EntitySize(allocSize))
- {
- }
-
- inline void* Allocate() {
+ {
+ }
+
+ inline void* Allocate() {
if (Y_UNLIKELY(Free_.Empty())) {
return Pool_.Allocate(AllocSize_, AlignSize_);
- }
-
- return Free_.PopFront()->ToPointer();
- }
-
+ }
+
+ return Free_.PopFront()->ToPointer();
+ }
+
inline void Release(void* ptr) noexcept {
- Free_.PushFront(TAlloc::FromPointer(ptr));
- }
-
+ Free_.PushFront(TAlloc::FromPointer(ptr));
+ }
+
inline size_t Size() const noexcept {
- return AllocSize_;
- }
-
-private:
- TMemoryPool Pool_;
+ return AllocSize_;
+ }
+
+private:
+ TMemoryPool Pool_;
const size_t AlignSize_;
- const size_t AllocSize_;
- TIntrusiveSList<TAlloc> Free_;
-};
-
-template <class T>
-class TSmallObjAllocator {
-public:
+ const size_t AllocSize_;
+ TIntrusiveSList<TAlloc> Free_;
+};
+
+template <class T>
+class TSmallObjAllocator {
+public:
using IGrowPolicy = TFixedSizeAllocator::IGrowPolicy;
-
- inline TSmallObjAllocator(IAllocator* alloc)
+
+ inline TSmallObjAllocator(IAllocator* alloc)
: Alloc_(sizeof(T), alignof(T), alloc)
- {
- }
-
- inline TSmallObjAllocator(IGrowPolicy* grow, IAllocator* alloc)
+ {
+ }
+
+ inline TSmallObjAllocator(IGrowPolicy* grow, IAllocator* alloc)
: Alloc_(sizeof(T), alignof(T), grow, alloc)
- {
- }
-
- inline T* Allocate() {
- return (T*)Alloc_.Allocate();
- }
-
+ {
+ }
+
+ inline T* Allocate() {
+ return (T*)Alloc_.Allocate();
+ }
+
inline void Release(T* t) noexcept {
- Alloc_.Release(t);
- }
-
-private:
- TFixedSizeAllocator Alloc_;
-};
-
-template <class T>
-class TObjectFromPool {
-public:
+ Alloc_.Release(t);
+ }
+
+private:
+ TFixedSizeAllocator Alloc_;
+};
+
+template <class T>
+class TObjectFromPool {
+public:
struct THeader {
void* Pool;
// Can't just use T because THeader must be standard layout type for offsetof to work.
alignas(T) char Obj[sizeof(T)];
};
using TPool = TSmallObjAllocator<THeader>;
-
- inline void* operator new(size_t, TPool* pool) {
+
+ inline void* operator new(size_t, TPool* pool) {
THeader* ret = pool->Allocate();
ret->Pool = pool;
return &ret->Obj;
- }
-
+ }
+
inline void operator delete(void* ptr, size_t) noexcept {
- DoDelete(ptr);
- }
-
+ DoDelete(ptr);
+ }
+
inline void operator delete(void* ptr, TPool*) noexcept {
- /*
- * this delete operator can be called automagically by compiler
- */
-
- DoDelete(ptr);
- }
-
-private:
+ /*
+ * this delete operator can be called automagically by compiler
+ */
+
+ DoDelete(ptr);
+ }
+
+private:
static inline void DoDelete(void* ptr) noexcept {
static_assert(std::is_standard_layout<THeader>::value, "offsetof is only defined for standard layout types");
THeader* header = (THeader*)((char*)ptr - offsetof(THeader, Obj));
((TPool*)header->Pool)->Release(header);
- }
-};
+ }
+};
diff --git a/util/memory/smallobj_ut.cpp b/util/memory/smallobj_ut.cpp
index ccd4d7e520..86003d1d53 100644
--- a/util/memory/smallobj_ut.cpp
+++ b/util/memory/smallobj_ut.cpp
@@ -1,33 +1,33 @@
-#include "smallobj.h"
-
+#include "smallobj.h"
+
#include <library/cpp/testing/unittest/registar.h>
-
+
#include <util/generic/hash_set.h>
-
-class TSmallObjAllocTest: public TTestBase {
- struct TClass: public TObjectFromPool<TClass> {
- char buf[125];
- };
-
- struct TErrClass: public TObjectFromPool<TErrClass> {
- inline TErrClass(bool t) {
- if (t) {
- throw 1;
- }
- }
- };
-
+
+class TSmallObjAllocTest: public TTestBase {
+ struct TClass: public TObjectFromPool<TClass> {
+ char buf[125];
+ };
+
+ struct TErrClass: public TObjectFromPool<TErrClass> {
+ inline TErrClass(bool t) {
+ if (t) {
+ throw 1;
+ }
+ }
+ };
+
struct TClass64: public TObjectFromPool<TClass64> {
alignas(64) ui64 Data = 0;
};
- UNIT_TEST_SUITE(TSmallObjAllocTest);
+ UNIT_TEST_SUITE(TSmallObjAllocTest);
UNIT_TEST(TestAlign)
UNIT_TEST(TestError)
- UNIT_TEST(TestAllocate)
- UNIT_TEST_SUITE_END();
-
-private:
+ UNIT_TEST(TestAllocate)
+ UNIT_TEST_SUITE_END();
+
+private:
void TestAlign() {
TClass64::TPool pool(TDefaultAllocator::Instance());
TClass64* f1 = new (&pool) TClass64;
@@ -41,47 +41,47 @@ private:
UNIT_ASSERT_VALUES_EQUAL((size_t)0, (size_t)(f4) & (alignof(TClass64) - 1));
}
- inline void TestError() {
- TErrClass::TPool pool(TDefaultAllocator::Instance());
- TErrClass* f = new (&pool) TErrClass(false);
-
- delete f;
-
- bool wasError = false;
-
- try {
- new (&pool) TErrClass(true);
- } catch (...) {
- wasError = true;
- }
-
- UNIT_ASSERT(wasError);
- UNIT_ASSERT_EQUAL(f, new (&pool) TErrClass(false));
- }
-
- inline void TestAllocate() {
- TClass::TPool pool(TDefaultAllocator::Instance());
+ inline void TestError() {
+ TErrClass::TPool pool(TDefaultAllocator::Instance());
+ TErrClass* f = new (&pool) TErrClass(false);
+
+ delete f;
+
+ bool wasError = false;
+
+ try {
+ new (&pool) TErrClass(true);
+ } catch (...) {
+ wasError = true;
+ }
+
+ UNIT_ASSERT(wasError);
+ UNIT_ASSERT_EQUAL(f, new (&pool) TErrClass(false));
+ }
+
+ inline void TestAllocate() {
+ TClass::TPool pool(TDefaultAllocator::Instance());
THashSet<TClass*> alloced;
-
- for (size_t i = 0; i < 10000; ++i) {
- TClass* c = new (&pool) TClass;
-
- UNIT_ASSERT_EQUAL(alloced.find(c), alloced.end());
- alloced.insert(c);
- }
-
+
+ for (size_t i = 0; i < 10000; ++i) {
+ TClass* c = new (&pool) TClass;
+
+ UNIT_ASSERT_EQUAL(alloced.find(c), alloced.end());
+ alloced.insert(c);
+ }
+
for (auto it : alloced) {
delete it;
- }
-
- for (size_t i = 0; i < 10000; ++i) {
- TClass* c = new (&pool) TClass;
-
- UNIT_ASSERT(alloced.find(c) != alloced.end());
- }
-
- UNIT_ASSERT_EQUAL(alloced.find(new (&pool) TClass), alloced.end());
- }
-};
-
-UNIT_TEST_SUITE_REGISTRATION(TSmallObjAllocTest);
+ }
+
+ for (size_t i = 0; i < 10000; ++i) {
+ TClass* c = new (&pool) TClass;
+
+ UNIT_ASSERT(alloced.find(c) != alloced.end());
+ }
+
+ UNIT_ASSERT_EQUAL(alloced.find(new (&pool) TClass), alloced.end());
+ }
+};
+
+UNIT_TEST_SUITE_REGISTRATION(TSmallObjAllocTest);
diff --git a/util/memory/tempbuf.cpp b/util/memory/tempbuf.cpp
index 5e6101f429..09a2d0f140 100644
--- a/util/memory/tempbuf.cpp
+++ b/util/memory/tempbuf.cpp
@@ -1,159 +1,159 @@
-#include "tempbuf.h"
-#include "addstorage.h"
-
-#include <util/system/tls.h>
-#include <util/system/yassert.h>
+#include "tempbuf.h"
+#include "addstorage.h"
+
+#include <util/system/tls.h>
+#include <util/system/yassert.h>
#include <util/system/defaults.h>
-#include <util/generic/intrlist.h>
-#include <util/generic/singleton.h>
-#include <util/generic/yexception.h>
+#include <util/generic/intrlist.h>
+#include <util/generic/singleton.h>
+#include <util/generic/yexception.h>
#include <utility>
-#include <util/thread/singleton.h>
-
+#include <util/thread/singleton.h>
+
#ifndef TMP_BUF_LEN
- #define TMP_BUF_LEN (64 * 1024)
+ #define TMP_BUF_LEN (64 * 1024)
#endif
-
-class TTempBuf::TImpl: public TRefCounted<TImpl, TSimpleCounter, TImpl> {
-public:
+
+class TTempBuf::TImpl: public TRefCounted<TImpl, TSimpleCounter, TImpl> {
+public:
inline TImpl(void* data, size_t size) noexcept
- : Data_(data)
- , Size_(size)
- , Offset_(0)
- {
- }
-
- /*
- * We do not really need 'virtual' here
- * but for compiler happiness...
- */
+ : Data_(data)
+ , Size_(size)
+ , Offset_(0)
+ {
+ }
+
+ /*
+ * We do not really need 'virtual' here
+ * but for compiler happiness...
+ */
virtual ~TImpl() = default;
-
+
inline void* Data() noexcept {
- return Data_;
- }
-
+ return Data_;
+ }
+
const void* Data() const noexcept {
- return Data_;
- }
+ return Data_;
+ }
inline size_t Size() const noexcept {
- return Size_;
- }
-
+ return Size_;
+ }
+
inline size_t Filled() const noexcept {
- return Offset_;
- }
-
+ return Offset_;
+ }
+
inline void Reset() noexcept {
- Offset_ = 0;
- }
-
+ Offset_ = 0;
+ }
+
inline size_t Left() const noexcept {
- return Size() - Filled();
- }
-
- void SetPos(size_t off) {
+ return Size() - Filled();
+ }
+
+ void SetPos(size_t off) {
Y_ASSERT(off <= Size());
- Offset_ = off;
- }
+ Offset_ = off;
+ }
- inline void Proceed(size_t off) {
+ inline void Proceed(size_t off) {
Y_ASSERT(off <= Left());
-
- Offset_ += off;
- }
-
+
+ Offset_ += off;
+ }
+
static inline void Destroy(TImpl* This) noexcept {
- This->Dispose();
- }
-
-protected:
+ This->Dispose();
+ }
+
+protected:
virtual void Dispose() noexcept = 0;
-
-private:
- void* Data_;
- size_t Size_;
- size_t Offset_;
-};
-
-namespace {
- class TTempBufManager;
-
- class TAllocedBuf: public TTempBuf::TImpl, public TAdditionalStorage<TAllocedBuf> {
- public:
- inline TAllocedBuf()
- : TImpl(AdditionalData(), AdditionalDataLength())
- {
- }
-
+
+private:
+ void* Data_;
+ size_t Size_;
+ size_t Offset_;
+};
+
+namespace {
+ class TTempBufManager;
+
+ class TAllocedBuf: public TTempBuf::TImpl, public TAdditionalStorage<TAllocedBuf> {
+ public:
+ inline TAllocedBuf()
+ : TImpl(AdditionalData(), AdditionalDataLength())
+ {
+ }
+
inline ~TAllocedBuf() override = default;
-
- private:
+
+ private:
void Dispose() noexcept override {
- delete this;
- }
- };
-
- class TPerThreadedBuf: public TTempBuf::TImpl, public TIntrusiveSListItem<TPerThreadedBuf> {
- friend class TTempBufManager;
-
- public:
+ delete this;
+ }
+ };
+
+ class TPerThreadedBuf: public TTempBuf::TImpl, public TIntrusiveSListItem<TPerThreadedBuf> {
+ friend class TTempBufManager;
+
+ public:
inline TPerThreadedBuf(TTempBufManager* manager) noexcept
- : TImpl(Data_, sizeof(Data_))
- , Manager_(manager)
- {
- }
-
+ : TImpl(Data_, sizeof(Data_))
+ , Manager_(manager)
+ {
+ }
+
inline ~TPerThreadedBuf() override = default;
-
- private:
+
+ private:
void Dispose() noexcept override;
-
- private:
- char Data_[TMP_BUF_LEN];
- TTempBufManager* Manager_;
- };
-
- class TTempBufManager {
- struct TDelete {
+
+ private:
+ char Data_[TMP_BUF_LEN];
+ TTempBufManager* Manager_;
+ };
+
+ class TTempBufManager {
+ struct TDelete {
inline void operator()(TPerThreadedBuf* p) noexcept {
- delete p;
- }
- };
-
- public:
+ delete p;
+ }
+ };
+
+ public:
inline TTempBufManager() noexcept {
- }
-
+ }
+
inline ~TTempBufManager() {
- TDelete deleter;
-
- Unused_.ForEach(deleter);
- }
-
+ TDelete deleter;
+
+ Unused_.ForEach(deleter);
+ }
+
inline TPerThreadedBuf* Acquire() {
- if (!Unused_.Empty()) {
- return Unused_.PopFront();
- }
-
- return new TPerThreadedBuf(this);
- }
-
+ if (!Unused_.Empty()) {
+ return Unused_.PopFront();
+ }
+
+ return new TPerThreadedBuf(this);
+ }
+
inline void Return(TPerThreadedBuf* buf) noexcept {
- buf->Reset();
- Unused_.PushFront(buf);
- }
-
- private:
- TIntrusiveSList<TPerThreadedBuf> Unused_;
- };
-}
-
-static inline TTempBufManager* TempBufManager() {
- return FastTlsSingletonWithPriority<TTempBufManager, 2>();
-}
-
+ buf->Reset();
+ Unused_.PushFront(buf);
+ }
+
+ private:
+ TIntrusiveSList<TPerThreadedBuf> Unused_;
+ };
+}
+
+static inline TTempBufManager* TempBufManager() {
+ return FastTlsSingletonWithPriority<TTempBufManager, 2>();
+}
+
static inline TTempBuf::TImpl* AcquireSmallBuffer(size_t size) {
#if defined(_asan_enabled_)
return new (size) TAllocedBuf();
@@ -164,53 +164,53 @@ static inline TTempBuf::TImpl* AcquireSmallBuffer(size_t size) {
}
void TPerThreadedBuf::Dispose() noexcept {
- if (Manager_ == TempBufManager()) {
- Manager_->Return(this);
- } else {
- delete this;
- }
-}
-
-TTempBuf::TTempBuf()
+ if (Manager_ == TempBufManager()) {
+ Manager_->Return(this);
+ } else {
+ delete this;
+ }
+}
+
+TTempBuf::TTempBuf()
: Impl_(AcquireSmallBuffer(TMP_BUF_LEN))
-{
-}
-
-/*
- * all magick is here:
- * if len <= TMP_BUF_LEN. then we get prealloced per threaded buffer
- * else allocate one in heap
- */
-static inline TTempBuf::TImpl* ConstructImpl(size_t len) {
- if (len <= TMP_BUF_LEN) {
+{
+}
+
+/*
+ * all magick is here:
+ * if len <= TMP_BUF_LEN. then we get prealloced per threaded buffer
+ * else allocate one in heap
+ */
+static inline TTempBuf::TImpl* ConstructImpl(size_t len) {
+ if (len <= TMP_BUF_LEN) {
return AcquireSmallBuffer(len);
- }
-
- return new (len) TAllocedBuf();
-}
-
-TTempBuf::TTempBuf(size_t len)
- : Impl_(ConstructImpl(len))
-{
-}
-
+ }
+
+ return new (len) TAllocedBuf();
+}
+
+TTempBuf::TTempBuf(size_t len)
+ : Impl_(ConstructImpl(len))
+{
+}
+
TTempBuf::TTempBuf(const TTempBuf&) noexcept = default;
-
+
TTempBuf::TTempBuf(TTempBuf&& b) noexcept
: Impl_(std::move(b.Impl_))
{
}
TTempBuf::~TTempBuf() = default;
-
+
TTempBuf& TTempBuf::operator=(const TTempBuf& b) noexcept {
- if (this != &b) {
- Impl_ = b.Impl_;
- }
-
- return *this;
-}
-
+ if (this != &b) {
+ Impl_ = b.Impl_;
+ }
+
+ return *this;
+}
+
TTempBuf& TTempBuf::operator=(TTempBuf&& b) noexcept {
if (this != &b) {
Impl_ = std::move(b.Impl_);
@@ -220,103 +220,103 @@ TTempBuf& TTempBuf::operator=(TTempBuf&& b) noexcept {
}
char* TTempBuf::Data() noexcept {
- return (char*)Impl_->Data();
-}
-
+ return (char*)Impl_->Data();
+}
+
const char* TTempBuf::Data() const noexcept {
- return static_cast<const char*>(Impl_->Data());
+ return static_cast<const char*>(Impl_->Data());
}
size_t TTempBuf::Size() const noexcept {
- return Impl_->Size();
-}
-
+ return Impl_->Size();
+}
+
char* TTempBuf::Current() noexcept {
- return Data() + Filled();
-}
-
+ return Data() + Filled();
+}
+
const char* TTempBuf::Current() const noexcept {
return Data() + Filled();
}
size_t TTempBuf::Filled() const noexcept {
- return Impl_->Filled();
-}
-
+ return Impl_->Filled();
+}
+
size_t TTempBuf::Left() const noexcept {
- return Impl_->Left();
-}
-
+ return Impl_->Left();
+}
+
void TTempBuf::Reset() noexcept {
- Impl_->Reset();
-}
-
+ Impl_->Reset();
+}
+
void TTempBuf::SetPos(size_t off) {
Impl_->SetPos(off);
}
char* TTempBuf::Proceed(size_t off) {
char* ptr = Current();
- Impl_->Proceed(off);
+ Impl_->Proceed(off);
return ptr;
-}
-
-void TTempBuf::Append(const void* data, size_t len) {
- if (len > Left()) {
- ythrow yexception() << "temp buf exhausted(" << Left() << ", " << len << ")";
- }
-
- memcpy(Current(), data, len);
- Proceed(len);
-}
-
+}
+
+void TTempBuf::Append(const void* data, size_t len) {
+ if (len > Left()) {
+ ythrow yexception() << "temp buf exhausted(" << Left() << ", " << len << ")";
+ }
+
+ memcpy(Current(), data, len);
+ Proceed(len);
+}
+
bool TTempBuf::IsNull() const noexcept {
return !Impl_;
}
-#if 0
- #include <util/datetime/cputimer.h>
-
- #define LEN (1024)
-
-void* allocaFunc() {
- return alloca(LEN);
-}
-
-int main() {
- const size_t num = 10000000;
- size_t tmp = 0;
-
- {
- CTimer t("alloca");
-
- for (size_t i = 0; i < num; ++i) {
- tmp += (size_t)allocaFunc();
- }
- }
-
- {
- CTimer t("log buffer");
-
- for (size_t i = 0; i < num; ++i) {
- TTempBuf buf(LEN);
-
- tmp += (size_t)buf.Data();
- }
- }
-
- {
- CTimer t("malloc");
-
- for (size_t i = 0; i < num; ++i) {
- void* ptr = malloc(LEN);
-
- tmp += (size_t)ptr;
-
- free(ptr);
- }
- }
-
- return 0;
-}
-#endif
+#if 0
+ #include <util/datetime/cputimer.h>
+
+ #define LEN (1024)
+
+void* allocaFunc() {
+ return alloca(LEN);
+}
+
+int main() {
+ const size_t num = 10000000;
+ size_t tmp = 0;
+
+ {
+ CTimer t("alloca");
+
+ for (size_t i = 0; i < num; ++i) {
+ tmp += (size_t)allocaFunc();
+ }
+ }
+
+ {
+ CTimer t("log buffer");
+
+ for (size_t i = 0; i < num; ++i) {
+ TTempBuf buf(LEN);
+
+ tmp += (size_t)buf.Data();
+ }
+ }
+
+ {
+ CTimer t("malloc");
+
+ for (size_t i = 0; i < num; ++i) {
+ void* ptr = malloc(LEN);
+
+ tmp += (size_t)ptr;
+
+ free(ptr);
+ }
+ }
+
+ return 0;
+}
+#endif
diff --git a/util/memory/tempbuf.h b/util/memory/tempbuf.h
index 02c376f658..334670eb1e 100644
--- a/util/memory/tempbuf.h
+++ b/util/memory/tempbuf.h
@@ -1,103 +1,103 @@
#pragma once
-
+
#include <util/system/defaults.h>
#include <util/generic/ptr.h>
-
-/*
- * This is really fast buffer for temporary data.
- * For small sizes it works almost fast as pure alloca()
- * (by using perthreaded list of free blocks),
- * for big sizes it works as fast as malloc()/operator new()/...
- */
-class TTempBuf {
-public:
- /*
- * we do not want many friends for this class :)
- */
- class TImpl;
-
- TTempBuf();
- TTempBuf(size_t len);
+
+/*
+ * This is really fast buffer for temporary data.
+ * For small sizes it works almost fast as pure alloca()
+ * (by using perthreaded list of free blocks),
+ * for big sizes it works as fast as malloc()/operator new()/...
+ */
+class TTempBuf {
+public:
+ /*
+ * we do not want many friends for this class :)
+ */
+ class TImpl;
+
+ TTempBuf();
+ TTempBuf(size_t len);
TTempBuf(const TTempBuf& b) noexcept;
TTempBuf(TTempBuf&& b) noexcept;
~TTempBuf();
-
+
TTempBuf& operator=(const TTempBuf& b) noexcept;
TTempBuf& operator=(TTempBuf&& b) noexcept;
-
- Y_PURE_FUNCTION char* Data() noexcept;
- Y_PURE_FUNCTION const char* Data() const noexcept;
+ Y_PURE_FUNCTION char* Data() noexcept;
+
+ Y_PURE_FUNCTION const char* Data() const noexcept;
- Y_PURE_FUNCTION char* Current() noexcept;
+ Y_PURE_FUNCTION char* Current() noexcept;
- Y_PURE_FUNCTION const char* Current() const noexcept;
+ Y_PURE_FUNCTION const char* Current() const noexcept;
- Y_PURE_FUNCTION size_t Size() const noexcept;
+ Y_PURE_FUNCTION size_t Size() const noexcept;
- Y_PURE_FUNCTION size_t Filled() const noexcept;
+ Y_PURE_FUNCTION size_t Filled() const noexcept;
- Y_PURE_FUNCTION size_t Left() const noexcept;
+ Y_PURE_FUNCTION size_t Left() const noexcept;
void Reset() noexcept;
- void SetPos(size_t off);
+ void SetPos(size_t off);
char* Proceed(size_t off);
- void Append(const void* data, size_t len);
-
- Y_PURE_FUNCTION bool IsNull() const noexcept;
-
-private:
- TIntrusivePtr<TImpl> Impl_;
-};
-
-template <typename T>
+ void Append(const void* data, size_t len);
+
+ Y_PURE_FUNCTION bool IsNull() const noexcept;
+
+private:
+ TIntrusivePtr<TImpl> Impl_;
+};
+
+template <typename T>
class TTempArray: private TTempBuf {
-private:
+private:
static T* TypedPointer(char* pointer) noexcept {
- return reinterpret_cast<T*>(pointer);
- }
+ return reinterpret_cast<T*>(pointer);
+ }
static const T* TypedPointer(const char* pointer) noexcept {
- return reinterpret_cast<const T*>(pointer);
- }
+ return reinterpret_cast<const T*>(pointer);
+ }
static constexpr size_t RawSize(const size_t size) noexcept {
- return size * sizeof(T);
- }
+ return size * sizeof(T);
+ }
static constexpr size_t TypedSize(const size_t size) noexcept {
- return size / sizeof(T);
- }
+ return size / sizeof(T);
+ }
-public:
+public:
TTempArray() = default;
- TTempArray(size_t len)
- : TTempBuf(RawSize(len))
- {
- }
-
+ TTempArray(size_t len)
+ : TTempBuf(RawSize(len))
+ {
+ }
+
T* Data() noexcept {
- return TypedPointer(TTempBuf::Data());
- }
+ return TypedPointer(TTempBuf::Data());
+ }
const T* Data() const noexcept {
- return TypedPointer(TTempBuf::Data());
- }
+ return TypedPointer(TTempBuf::Data());
+ }
T* Current() noexcept {
- return TypedPointer(TTempBuf::Current());
- }
-
+ return TypedPointer(TTempBuf::Current());
+ }
+
const T* Current() const noexcept {
- return TypedPointer(TTempBuf::Current());
- }
+ return TypedPointer(TTempBuf::Current());
+ }
size_t Size() const noexcept {
- return TypedSize(TTempBuf::Size());
- }
+ return TypedSize(TTempBuf::Size());
+ }
size_t Filled() const noexcept {
- return TypedSize(TTempBuf::Filled());
- }
-
+ return TypedSize(TTempBuf::Filled());
+ }
+
T* Proceed(size_t off) {
return (T*)TTempBuf::Proceed(RawSize(off));
- }
+ }
};
diff --git a/util/memory/tempbuf_ut.cpp b/util/memory/tempbuf_ut.cpp
index 3c6dc5a221..d6bcf9d546 100644
--- a/util/memory/tempbuf_ut.cpp
+++ b/util/memory/tempbuf_ut.cpp
@@ -1,69 +1,69 @@
-#include "tempbuf.h"
-
+#include "tempbuf.h"
+
#include <utility>
#include <library/cpp/testing/unittest/registar.h>
-
-class TTempBufTest: public TTestBase {
- UNIT_TEST_SUITE(TTempBufTest);
- UNIT_TEST(TestCreate);
- UNIT_TEST(TestOps);
+
+class TTempBufTest: public TTestBase {
+ UNIT_TEST_SUITE(TTempBufTest);
+ UNIT_TEST(TestCreate);
+ UNIT_TEST(TestOps);
UNIT_TEST(TestMoveCtor);
- UNIT_TEST(TestAppend);
+ UNIT_TEST(TestAppend);
UNIT_TEST(TestProceed);
- UNIT_TEST_SUITE_END();
-
-public:
- void TestCreate();
- void TestOps();
+ UNIT_TEST_SUITE_END();
+
+public:
+ void TestCreate();
+ void TestOps();
void TestMoveCtor();
void TestProceed();
-
- void TestAppend() {
- TTempBuf tmp;
-
- tmp.Append("a", 1);
- tmp.Append("bc", 2);
- tmp.Append("def", 3);
-
- UNIT_ASSERT_EQUAL(tmp.Filled(), 6);
+
+ void TestAppend() {
+ TTempBuf tmp;
+
+ tmp.Append("a", 1);
+ tmp.Append("bc", 2);
+ tmp.Append("def", 3);
+
+ UNIT_ASSERT_EQUAL(tmp.Filled(), 6);
UNIT_ASSERT_EQUAL(TString(tmp.Data(), tmp.Filled()), "abcdef");
- }
-};
-
-UNIT_TEST_SUITE_REGISTRATION(TTempBufTest);
-
-void TTempBufTest::TestCreate() {
- const size_t num = 1000000;
- size_t tmp = 0;
- const size_t len = 4096;
-
- for (size_t i = 0; i < num; ++i) {
- TTempBuf buf(len);
-
- tmp += (size_t)buf.Data();
- }
-
- UNIT_ASSERT(tmp != 0);
-}
-
-void TTempBufTest::TestOps() {
- TTempBuf tmp(201);
-
- tmp.Proceed(100);
-
- UNIT_ASSERT_EQUAL(tmp.Current() - tmp.Data(), 100);
- UNIT_ASSERT(tmp.Left() >= 101);
- UNIT_ASSERT(tmp.Size() >= 201);
- UNIT_ASSERT_EQUAL(tmp.Filled(), 100);
-
- tmp.Reset();
-
- UNIT_ASSERT_EQUAL(tmp.Current(), tmp.Data());
- UNIT_ASSERT(tmp.Left() >= 201);
- UNIT_ASSERT(tmp.Size() >= 201);
- UNIT_ASSERT_EQUAL(tmp.Filled(), 0);
-}
+ }
+};
+
+UNIT_TEST_SUITE_REGISTRATION(TTempBufTest);
+
+void TTempBufTest::TestCreate() {
+ const size_t num = 1000000;
+ size_t tmp = 0;
+ const size_t len = 4096;
+
+ for (size_t i = 0; i < num; ++i) {
+ TTempBuf buf(len);
+
+ tmp += (size_t)buf.Data();
+ }
+
+ UNIT_ASSERT(tmp != 0);
+}
+
+void TTempBufTest::TestOps() {
+ TTempBuf tmp(201);
+
+ tmp.Proceed(100);
+
+ UNIT_ASSERT_EQUAL(tmp.Current() - tmp.Data(), 100);
+ UNIT_ASSERT(tmp.Left() >= 101);
+ UNIT_ASSERT(tmp.Size() >= 201);
+ UNIT_ASSERT_EQUAL(tmp.Filled(), 100);
+
+ tmp.Reset();
+
+ UNIT_ASSERT_EQUAL(tmp.Current(), tmp.Data());
+ UNIT_ASSERT(tmp.Left() >= 201);
+ UNIT_ASSERT(tmp.Size() >= 201);
+ UNIT_ASSERT_EQUAL(tmp.Filled(), 0);
+}
void TTempBufTest::TestMoveCtor() {
TTempBuf src;
diff --git a/util/memory/ut/ya.make b/util/memory/ut/ya.make
index 2cff8d8cd0..d3a988617d 100644
--- a/util/memory/ut/ya.make
+++ b/util/memory/ut/ya.make
@@ -1,14 +1,14 @@
-UNITTEST_FOR(util)
+UNITTEST_FOR(util)
OWNER(g:util)
SUBSCRIBER(g:util-subscribers)
SRCS(
- memory/addstorage_ut.cpp
- memory/blob_ut.cpp
- memory/pool_ut.cpp
- memory/smallobj_ut.cpp
- memory/tempbuf_ut.cpp
+ memory/addstorage_ut.cpp
+ memory/blob_ut.cpp
+ memory/pool_ut.cpp
+ memory/smallobj_ut.cpp
+ memory/tempbuf_ut.cpp
)
INCLUDE(${ARCADIA_ROOT}/util/tests/ya_util_tests.inc)