123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- #include "blob.h"
- #include "ref.h"
- #include <library/cpp/yt/malloc/malloc.h>
- namespace NYT {
- ////////////////////////////////////////////////////////////////////////////////
- static constexpr size_t InitialBlobCapacity = 16;
- static constexpr double BlobCapacityMultiplier = 1.5;
- TBlob::TBlob(
- TRefCountedTypeCookie tagCookie,
- size_t size,
- bool initializeStorage,
- bool pageAligned)
- : PageAligned_(pageAligned)
- {
- SetTagCookie(tagCookie);
- if (size == 0) {
- Reset();
- } else {
- Allocate(std::max(size, InitialBlobCapacity));
- Size_ = size;
- if (initializeStorage) {
- ::memset(Begin_, 0, Size_);
- }
- }
- }
- TBlob::TBlob(
- TRefCountedTypeCookie tagCookie,
- TRef data,
- bool pageAligned)
- : PageAligned_(pageAligned)
- {
- SetTagCookie(tagCookie);
- Reset();
- Append(data);
- }
- TBlob::TBlob(const TBlob& other)
- : PageAligned_(other.PageAligned_)
- {
- SetTagCookie(other);
- if (other.Size_ == 0) {
- Reset();
- } else {
- Allocate(std::max(InitialBlobCapacity, other.Size_));
- ::memcpy(Begin_, other.Begin_, other.Size_);
- Size_ = other.Size_;
- }
- }
- TBlob::TBlob(TBlob&& other) noexcept
- : Begin_(other.Begin_)
- , Size_(other.Size_)
- , Capacity_(other.Capacity_)
- , PageAligned_(other.PageAligned_)
- {
- SetTagCookie(other);
- other.Reset();
- }
- TBlob::~TBlob()
- {
- Free();
- }
- void TBlob::Reserve(size_t newCapacity)
- {
- if (newCapacity > Capacity_) {
- Reallocate(newCapacity);
- }
- }
- void TBlob::Resize(size_t newSize, bool initializeStorage)
- {
- if (newSize > Size_) {
- if (newSize > Capacity_) {
- size_t newCapacity;
- if (Capacity_ == 0) {
- newCapacity = std::max(InitialBlobCapacity, newSize);
- } else {
- newCapacity = std::max(static_cast<size_t>(Capacity_ * BlobCapacityMultiplier), newSize);
- }
- Reallocate(newCapacity);
- }
- if (initializeStorage) {
- ::memset(Begin_ + Size_, 0, newSize - Size_);
- }
- }
- Size_ = newSize;
- }
- TBlob& TBlob::operator = (const TBlob& rhs)
- {
- if (this != &rhs) {
- this->~TBlob();
- new(this) TBlob(rhs);
- }
- return *this;
- }
- TBlob& TBlob::operator = (TBlob&& rhs) noexcept
- {
- if (this != &rhs) {
- this->~TBlob();
- new(this) TBlob(std::move(rhs));
- }
- return *this;
- }
- void TBlob::Append(const void* data, size_t size)
- {
- if (Size_ + size > Capacity_) {
- Resize(Size_ + size, false);
- ::memcpy(Begin_ + Size_ - size, data, size);
- } else {
- ::memcpy(Begin_ + Size_, data, size);
- Size_ += size;
- }
- }
- void TBlob::Append(TRef ref)
- {
- Append(ref.Begin(), ref.Size());
- }
- void TBlob::Append(char ch)
- {
- if (Size_ + 1 > Capacity_) {
- Resize(Size_ + 1, false);
- Begin_[Size_ - 1] = ch;
- } else {
- Begin_[Size_++] = ch;
- }
- }
- void TBlob::Reset()
- {
- Begin_ = nullptr;
- Size_ = Capacity_ = 0;
- }
- char* TBlob::DoAllocate(size_t size)
- {
- return static_cast<char*>(PageAligned_
- ? ::aligned_malloc(size, GetPageSize())
- : ::malloc(size));
- }
- void TBlob::Allocate(size_t newCapacity)
- {
- YT_VERIFY(!Begin_);
- Begin_ = DoAllocate(newCapacity);
- Capacity_ = newCapacity;
- #ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TRefCountedTrackerFacade::AllocateTagInstance(TagCookie_);
- TRefCountedTrackerFacade::AllocateSpace(TagCookie_, newCapacity);
- #endif
- }
- void TBlob::Reallocate(size_t newCapacity)
- {
- if (!Begin_) {
- Allocate(newCapacity);
- return;
- }
- char* newBegin = DoAllocate(newCapacity);
- ::memcpy(newBegin, Begin_, Size_);
- ::free(Begin_);
- #ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TRefCountedTrackerFacade::AllocateSpace(TagCookie_, newCapacity);
- TRefCountedTrackerFacade::FreeSpace(TagCookie_, Capacity_);
- #endif
- Begin_ = newBegin;
- Capacity_ = newCapacity;
- }
- void TBlob::Free()
- {
- if (!Begin_) {
- return;
- }
- ::free(Begin_);
- #ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TRefCountedTrackerFacade::FreeTagInstance(TagCookie_);
- TRefCountedTrackerFacade::FreeSpace(TagCookie_, Capacity_);
- #endif
- Reset();
- }
- void TBlob::SetTagCookie(TRefCountedTypeCookie tagCookie)
- {
- #ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TagCookie_ = tagCookie;
- #endif
- }
- void TBlob::SetTagCookie(const TBlob& other)
- {
- #ifdef YT_ENABLE_REF_COUNTED_TRACKING
- TagCookie_ = other.TagCookie_;
- #endif
- }
- void swap(TBlob& left, TBlob& right)
- {
- if (&left != &right) {
- std::swap(left.Begin_, right.Begin_);
- std::swap(left.Size_, right.Size_);
- std::swap(left.Capacity_, right.Capacity_);
- std::swap(left.PageAligned_, right.PageAligned_);
- #ifdef YT_ENABLE_REF_COUNTED_TRACKING
- std::swap(left.TagCookie_, right.TagCookie_);
- #endif
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- } // namespace NYT
|