blob: 0a1318c231088d00f306cc4ab476f265431d9ab9 (
plain) (
tree)
|
|
#pragma once
#include "ref.h"
#include "ref_counted.h"
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
//! Default memory tag for TBlob.
struct TDefaultBlobTag
{ };
//! A home-grown optimized replacement for |std::vector<char>| suitable for carrying
//! large chunks of data.
/*!
* Compared to |std::vector<char>|, this class supports uninitialized allocations
* when explicitly requested to.
*/
class TBlob
{
public:
//! Constructs a blob with a given size.
explicit TBlob(
TRefCountedTypeCookie tagCookie = GetRefCountedTypeCookie<TDefaultBlobTag>(),
size_t size = 0,
bool initiailizeStorage = true,
bool pageAligned = false);
//! Copies a chunk of memory into a new instance.
TBlob(
TRefCountedTypeCookie tagCookie,
TRef data,
bool pageAligned = false);
//! Copies the data.
TBlob(const TBlob& other);
//! Moves the data (takes the ownership).
TBlob(TBlob&& other) noexcept;
//! Reclaims the memory.
~TBlob();
//! Ensures that capacity is at least #capacity.
void Reserve(size_t newCapacity);
//! Changes the size to #newSize.
/*!
* If #size exceeds the current capacity,
* we make sure the new capacity grows exponentially.
* Hence calling #Resize N times to increase the size by N only
* takes amortized O(1) time per call.
*/
void Resize(size_t newSize, bool initializeStorage = true);
//! Returns the start pointer.
Y_FORCE_INLINE const char* Begin() const
{
return Begin_;
}
//! Returns the start pointer.
Y_FORCE_INLINE char* Begin()
{
return Begin_;
}
//! Returns the end pointer.
Y_FORCE_INLINE const char* End() const
{
return Begin_ + Size_;
}
//! Returns the end pointer.
Y_FORCE_INLINE char* End()
{
return Begin_ + Size_;
}
//! Returns the size.
Y_FORCE_INLINE size_t size() const
{
return Size_;
}
//! Returns the size.
Y_FORCE_INLINE size_t Size() const
{
return Size_;
}
//! Returns the capacity.
Y_FORCE_INLINE size_t Capacity() const
{
return Capacity_;
}
//! Returns the TStringBuf instance for the occupied part of the blob.
Y_FORCE_INLINE TStringBuf ToStringBuf() const
{
return TStringBuf(Begin_, Size_);
}
//! Returns the TRef instance for the occupied part of the blob.
Y_FORCE_INLINE TRef ToRef() const
{
return TRef(Begin_, Size_);
}
//! Provides by-value access to the underlying storage.
Y_FORCE_INLINE char operator [] (size_t index) const
{
return Begin_[index];
}
//! Provides by-ref access to the underlying storage.
Y_FORCE_INLINE char& operator [] (size_t index)
{
return Begin_[index];
}
//! Clears the instance but does not reclaim the memory.
Y_FORCE_INLINE void Clear()
{
Size_ = 0;
}
//! Returns |true| if size is zero.
Y_FORCE_INLINE bool IsEmpty() const
{
return Size_ == 0;
}
//! Overwrites the current instance.
TBlob& operator = (const TBlob& rhs);
//! Takes the ownership.
TBlob& operator = (TBlob&& rhs) noexcept;
//! Appends a chunk of memory to the end.
void Append(const void* data, size_t size);
//! Appends a chunk of memory to the end.
void Append(TRef ref);
//! Appends a single char to the end.
void Append(char ch);
//! Swaps the current and other instances
void Swap(TBlob& other);
friend void swap(TBlob& left, TBlob& right);
private:
char* Begin_ = nullptr;
size_t Size_ = 0;
size_t Capacity_ = 0;
bool PageAligned_ = false;
#ifdef YT_ENABLE_REF_COUNTED_TRACKING
TRefCountedTypeCookie TagCookie_ = NullRefCountedTypeCookie;
#endif
char* DoAllocate(size_t newCapacity);
void Allocate(size_t newCapacity);
void Reallocate(size_t newCapacity);
void Free();
void Reset();
void SetTagCookie(TRefCountedTypeCookie tagCookie);
void SetTagCookie(const TBlob& other);
};
void swap(TBlob& left, TBlob& right);
////////////////////////////////////////////////////////////////////////////////
} // namespace NYT
|