diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/yt/memory/ref.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/yt/memory/ref.h')
-rw-r--r-- | library/cpp/yt/memory/ref.h | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/library/cpp/yt/memory/ref.h b/library/cpp/yt/memory/ref.h new file mode 100644 index 0000000000..73d19d9013 --- /dev/null +++ b/library/cpp/yt/memory/ref.h @@ -0,0 +1,384 @@ +#pragma once + +#include "new.h" +#include "range.h" +#include "shared_range.h" + +#include <type_traits> + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +// Forward declaration. +class TBlob; + +//! A non-owning reference to a range of memory. +class TRef + : public TRange<char> +{ +public: + //! Creates a null TRef. + TRef() = default; + + //! Creates a TRef for a given block of memory. + TRef(const void* data, size_t size); + + //! Creates a TRef for a given range of memory. + TRef(const void* begin, const void* end); + + //! Creates an empty TRef. + static TRef MakeEmpty(); + + //! Creates a non-owning TRef for a given blob. + static TRef FromBlob(const TBlob& blob); + + //! Creates a non-owning TRef for a given string. + static TRef FromString(const TString& str); + + //! Creates a non-owning TRef for a given stringbuf. + static TRef FromStringBuf(TStringBuf strBuf); + + //! Creates a non-owning TRef for a given pod structure. + template <class T> + static TRef FromPod(const T& data); + + //! Creates a TRef for a part of existing range. + TRef Slice(size_t startOffset, size_t endOffset) const; + + //! Compares the content for bitwise equality. + static bool AreBitwiseEqual(TRef lhs, TRef rhs); +}; + +//////////////////////////////////////////////////////////////////////////////// + +//! A non-owning reference to a mutable range of memory. +//! Use with caution :) +class TMutableRef + : public TMutableRange<char> +{ +public: + //! Creates a null TMutableRef. + //! Note empty TMutableRef is not the same as null TMutableRef. + //! `operator bool` can be used to check if ref is nonnull. + TMutableRef() = default; + + //! Creates a TMutableRef for a given block of memory. + TMutableRef(void* data, size_t size); + + //! Creates a TMutableRef for a given range of memory. + TMutableRef(void* begin, void* end); + + //! Creates an empty TMutableRef. + static TMutableRef MakeEmpty(); + + //! Converts a TMutableRef to TRef. + operator TRef() const; + + //! Creates a non-owning TMutableRef for a given blob. + static TMutableRef FromBlob(TBlob& blob); + + //! Creates a non-owning TMutableRef for a given pod structure. + template <class T> + static TMutableRef FromPod(T& data); + + //! Creates a non-owning TMutableRef for a given string. + //! Ensures that the string is not shared. + static TMutableRef FromString(TString& str); + + //! Creates a TMutableRef for a part of existing range. + TMutableRef Slice(size_t startOffset, size_t endOffset) const; +}; + +//////////////////////////////////////////////////////////////////////////////// + +//! Default tag type for memory blocks allocated via TSharedRef. +/*! + * Each newly allocated TSharedRef blob is associated with a tag type + * that appears in ref-counted statistics. + */ +struct TDefaultSharedBlobTag { }; + +//! A reference to a range of memory with shared ownership. +class TSharedRef + : public TSharedRange<char> +{ +public: + //! Creates a null TSharedRef. + TSharedRef() = default; + + //! Creates a TSharedRef with a given holder. + TSharedRef(TRef ref, THolderPtr holder); + + //! Creates a TSharedRef from a pointer and length. + TSharedRef(const void* data, size_t length, THolderPtr holder); + + //! Creates a TSharedRef from a range. + TSharedRef(const void* begin, const void* end, THolderPtr holder); + + //! Creates an empty TSharedRef. + static TSharedRef MakeEmpty(); + + //! Converts a TSharedRef to TRef. + operator TRef() const; + + + //! Creates a TSharedRef from a string. + //! Since strings are ref-counted, no data is copied. + //! The memory is marked with a given tag. + template <class TTag> + static TSharedRef FromString(TString str); + + //! Creates a TSharedRef from a string. + //! Since strings are ref-counted, no data is copied. + //! The memory is marked with TDefaultSharedBlobTag. + static TSharedRef FromString(TString str); + + //! Creates a TSharedRef reference from a string. + //! Since strings are ref-counted, no data is copied. + //! The memory is marked with a given tag. + static TSharedRef FromString(TString str, TRefCountedTypeCookie tagCookie); + + //! Creates a TSharedRef for a given blob taking ownership of its content. + static TSharedRef FromBlob(TBlob&& blob); + + //! Creates a copy of a given TRef. + //! The memory is marked with a given tag. + static TSharedRef MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie); + + //! Creates a copy of a given TRef. + //! The memory is marked with a given tag. + template <class TTag> + static TSharedRef MakeCopy(TRef ref); + + //! Creates a TSharedRef for a part of existing range. + TSharedRef Slice(size_t startOffset, size_t endOffset) const; + + //! Creates a TSharedRef for a part of existing range. + TSharedRef Slice(const void* begin, const void* end) const; + + //! Creates a vector of slices with specified size. + std::vector<TSharedRef> Split(size_t partSize) const; + +private: + friend class TSharedRefArrayImpl; +}; + +//////////////////////////////////////////////////////////////////////////////// + +//! A reference to a mutable range of memory with shared ownership. +//! Use with caution :) +class TSharedMutableRef + : public TSharedMutableRange<char> +{ +public: + //! Creates a null TSharedMutableRef. + TSharedMutableRef() = default; + + //! Creates a TSharedMutableRef with a given holder. + TSharedMutableRef(const TMutableRef& ref, THolderPtr holder); + + //! Creates a TSharedMutableRef from a pointer and length. + TSharedMutableRef(void* data, size_t length, THolderPtr holder); + + //! Creates a TSharedMutableRef from a range. + TSharedMutableRef(void* begin, void* end, THolderPtr holder); + + //! Creates an empty TSharedMutableRef. + static TSharedMutableRef MakeEmpty(); + + //! Converts a TSharedMutableRef to TMutableRef. + operator TMutableRef() const; + + //! Converts a TSharedMutableRef to TSharedRef. + operator TSharedRef() const; + + //! Converts a TSharedMutableRef to TRef. + operator TRef() const; + + + //! Allocates a new shared block of memory. + //! The memory is marked with a given tag. + template <class TTag> + static TSharedMutableRef Allocate(size_t size, bool initializeStorage = true); + + //! Allocates a new shared block of memory. + //! The memory is marked with TDefaultSharedBlobTag. + static TSharedMutableRef Allocate(size_t size, bool initializeStorage = true); + + //! Allocates a new shared block of memory. + //! The memory is marked with a given tag. + static TSharedMutableRef Allocate(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie); + + //! Allocates a new page aligned shared block of memory. + //! #size must be divisible by page size. + //! The memory is marked with a given tag. + template <class TTag> + static TSharedMutableRef AllocatePageAligned(size_t size, bool initializeStorage = true); + + //! Allocates a new page aligned shared block of memory. + //! #size must be divisible by page size. + //! The memory is marked with TDefaultSharedBlobTag. + static TSharedMutableRef AllocatePageAligned(size_t size, bool initializeStorage = true); + + //! Allocates a new page aligned shared block of memory. + //! #size must be divisible by page size. + //! The memory is marked with a given tag. + static TSharedMutableRef AllocatePageAligned(size_t size, bool initializeStorage, TRefCountedTypeCookie tagCookie); + + //! Creates a TSharedMutableRef for the whole blob taking ownership of its content. + static TSharedMutableRef FromBlob(TBlob&& blob); + + //! Creates a copy of a given TRef. + //! The memory is marked with a given tag. + static TSharedMutableRef MakeCopy(TRef ref, TRefCountedTypeCookie tagCookie); + + //! Creates a copy of a given TRef. + //! The memory is marked with a given tag. + template <class TTag> + static TSharedMutableRef MakeCopy(TRef ref); + + //! Creates a reference for a part of existing range. + TSharedMutableRef Slice(size_t startOffset, size_t endOffset) const; + + //! Creates a reference for a part of existing range. + TSharedMutableRef Slice(void* begin, void* end) const; +}; + +//////////////////////////////////////////////////////////////////////////////// + +DECLARE_REFCOUNTED_CLASS(TSharedRefArrayImpl) + +//! A smart-pointer to a ref-counted immutable sequence of TSharedRef-s. +class TSharedRefArray +{ +public: + TSharedRefArray() = default; + TSharedRefArray(const TSharedRefArray& other); + TSharedRefArray(TSharedRefArray&& other) noexcept; + + explicit TSharedRefArray(const TSharedRef& part); + explicit TSharedRefArray(TSharedRef&& part); + + struct TCopyParts + { }; + struct TMoveParts + { }; + + template <class TParts> + TSharedRefArray(const TParts& parts, TCopyParts); + template <class TParts> + TSharedRefArray(TParts&& parts, TMoveParts); + + TSharedRefArray& operator = (const TSharedRefArray& other); + TSharedRefArray& operator = (TSharedRefArray&& other); + + explicit operator bool() const; + + void Reset(); + + size_t Size() const; + size_t size() const; + i64 ByteSize() const; + bool Empty() const; + const TSharedRef& operator [] (size_t index) const; + + const TSharedRef* Begin() const; + const TSharedRef* End() const; + + std::vector<TSharedRef> ToVector() const; + +private: + friend class TSharedRefArrayBuilder; + + TSharedRefArrayImplPtr Impl_; + + explicit TSharedRefArray(TSharedRefArrayImplPtr impl); + + template <class... As> + static TSharedRefArrayImplPtr NewImpl( + size_t size, + size_t poolCapacity, + TRefCountedTypeCookie cookie, + As&&... args); +}; + +// STL interop. +const TSharedRef* begin(const TSharedRefArray& array); +const TSharedRef* end(const TSharedRefArray& array); + +//////////////////////////////////////////////////////////////////////////////// + +struct TDefaultSharedRefArrayBuilderTag { }; + +//! A helper for creating TSharedRefArray. +class TSharedRefArrayBuilder +{ +public: + //! Creates a builder instance. + /* + * The user must provide the total (resulting) part count in #size. + * + * Additionally, the user may request a certain memory pool of size #poolCapacity + * to be created. Parts occupiying space in the above pool are created with #AllocateAndAdd + * calls. + * + * The pool (if any) and the array are created within a single memory allocation tagged with + * #tagCookie. + * + * If less than #size parts are added, the trailing ones are null. + */ + explicit TSharedRefArrayBuilder( + size_t size, + size_t poolCapacity = 0, + TRefCountedTypeCookie tagCookie = GetRefCountedTypeCookie<TDefaultSharedRefArrayBuilderTag>()); + + //! Adds an existing TSharedRef part to the constructed array. + void Add(TSharedRef part); + + //! Allocates #size memory from the pool and adds a part to the constuctured array. + /*! + * The resulting TMutableRef enables the user to fill the just-created part appropriately. + * The total sum of #size during all #AllocateAndAll calls must now exceed #allocationCapacity + * passed to the ctor. + * + * The memory is being claimed from the pool contiguously; the user must + * take care of the alignment issues on its own. + */ + TMutableRef AllocateAndAdd(size_t size); + + //! Finalizes the construction; returns the constructed TSharedRefArray. + TSharedRefArray Finish(); + +private: + const size_t AllocationCapacity_; + TSharedRefArrayImplPtr Impl_; + char* CurrentAllocationPtr_; + size_t CurrentPartIndex_ = 0; +}; + + +//////////////////////////////////////////////////////////////////////////////// + +TString ToString(TRef ref); +TString ToString(const TMutableRef& ref); +TString ToString(const TSharedRef& ref); +TString ToString(const TSharedMutableRef& ref); + +size_t GetPageSize(); +size_t RoundUpToPage(size_t bytes); + +size_t GetByteSize(TRef ref); +size_t GetByteSize(const TSharedRefArray& array); +template <class T> +size_t GetByteSize(TRange<T> parts); +template <class T> +size_t GetByteSize(const std::vector<T>& parts); + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT + +#define REF_INL_H_ +#include "ref-inl.h" +#undef REF_INL_H_ |