aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/memory/ref.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/yt/memory/ref.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/yt/memory/ref.h')
-rw-r--r--library/cpp/yt/memory/ref.h384
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_