blob.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #pragma once
  2. #include <util/generic/fwd.h>
  3. #include <util/generic/strbuf.h>
  4. #include <util/generic/utility.h>
  5. #include <util/system/defaults.h>
  6. class TMemoryMap;
  7. class IInputStream;
  8. class TFile;
  9. class TBuffer;
  10. enum class EMappingMode {
  11. /// Just mmap a file allowing lazy page loading at access
  12. Standard,
  13. /// Same as previous but warmup the buffer with sequential access to it's data
  14. Precharged,
  15. /// Try to lock file in memory so that it doesn't wash away. See mlock(2)
  16. Locked
  17. };
  18. /// @addtogroup BLOBs
  19. /// @{
  20. class TBlob {
  21. public:
  22. class TBase {
  23. public:
  24. inline TBase() noexcept = default;
  25. virtual ~TBase() = default;
  26. virtual void Ref() noexcept = 0;
  27. virtual void UnRef() noexcept = 0;
  28. };
  29. private:
  30. struct TStorage {
  31. const void* Data;
  32. size_t Length;
  33. TBase* Base;
  34. inline TStorage(const void* data, size_t length, TBase* base) noexcept
  35. : Data(data)
  36. , Length(length)
  37. , Base(base)
  38. {
  39. }
  40. inline ~TStorage() = default;
  41. inline void Swap(TStorage& r) noexcept {
  42. DoSwap(Data, r.Data);
  43. DoSwap(Length, r.Length);
  44. DoSwap(Base, r.Base);
  45. }
  46. };
  47. public:
  48. using value_type = ui8;
  49. using const_reference = const value_type&;
  50. using const_pointer = const value_type*;
  51. using const_iterator = const_pointer;
  52. /**
  53. * Constructs a null blob (data array points to nullptr).
  54. */
  55. TBlob() noexcept
  56. : S_(nullptr, 0, nullptr)
  57. {
  58. }
  59. inline TBlob(const TBlob& r) noexcept
  60. : S_(r.S_)
  61. {
  62. Ref();
  63. }
  64. TBlob(TBlob&& r) noexcept
  65. : TBlob()
  66. {
  67. this->Swap(r);
  68. }
  69. inline TBlob(const void* data, size_t length, TBase* base) noexcept
  70. : S_(data, length, base)
  71. {
  72. Ref();
  73. }
  74. inline ~TBlob() {
  75. UnRef();
  76. }
  77. inline TBlob& operator=(const TBlob& r) noexcept {
  78. TBlob(r).Swap(*this);
  79. return *this;
  80. }
  81. /// Swaps content of two data arrays.
  82. inline void Swap(TBlob& r) noexcept {
  83. S_.Swap(r.S_);
  84. }
  85. /// Returns a const reference to the data array.
  86. inline const void* Data() const noexcept {
  87. return S_.Data;
  88. }
  89. /// Returns the size of the data array in bytes.
  90. inline size_t Length() const noexcept {
  91. return S_.Length;
  92. }
  93. /// Checks if the object has an empty data array.
  94. Y_PURE_FUNCTION inline bool Empty() const noexcept {
  95. return !Length();
  96. }
  97. /// Checks if the blob owns data
  98. Y_PURE_FUNCTION inline bool OwnsData() const noexcept {
  99. return S_.Base != nullptr;
  100. }
  101. /// Checks if the object has a data array.
  102. inline bool IsNull() const noexcept {
  103. return !Data();
  104. }
  105. /// Returns a const pointer of char type to the data array.
  106. inline const char* AsCharPtr() const noexcept {
  107. return (const char*)Data();
  108. }
  109. /// Returns a const pointer of unsigned char type to the data array.
  110. inline const unsigned char* AsUnsignedCharPtr() const noexcept {
  111. return (const unsigned char*)Data();
  112. }
  113. inline TStringBuf AsStringBuf() const noexcept {
  114. return TStringBuf(AsCharPtr(), size());
  115. }
  116. /// Drops the data array.
  117. inline void Drop() noexcept {
  118. TBlob().Swap(*this);
  119. }
  120. /*
  121. * Some stl-like methods
  122. */
  123. /// Returns a const reference to the data array.
  124. /// result type is const ui8* which is not consistent with Data method above
  125. /// but it's consistent with operator[], Begin and End methods below
  126. /// Also it allows us to construct TArrayRef from TBlob
  127. inline const_pointer data() const noexcept {
  128. return static_cast<const_pointer>(Data());
  129. }
  130. /// Returns the size of the data array in bytes.
  131. inline size_t size() const noexcept {
  132. return Length();
  133. }
  134. /// Returns the size of the data array in bytes.
  135. inline size_t Size() const noexcept {
  136. return Length();
  137. }
  138. /// Standard iterator.
  139. inline const_iterator Begin() const noexcept {
  140. return AsUnsignedCharPtr();
  141. }
  142. /// Standard iterator.
  143. inline const_iterator End() const noexcept {
  144. return Begin() + Size();
  145. }
  146. inline value_type operator[](size_t n) const noexcept {
  147. return *(Begin() + n);
  148. }
  149. /// Shortcut to SubBlob(0, len)
  150. TBlob SubBlob(size_t len) const;
  151. /// Creates a new object from the provided range [begin, end) of internal data. No memory allocation and no copy.
  152. /// @details Increments the refcounter of the current object
  153. TBlob SubBlob(size_t begin, size_t end) const;
  154. /// Calls Copy() for the internal data.
  155. TBlob DeepCopy() const;
  156. /// Creates a new blob with a single-threaded (non atomic) refcounter. Dynamically allocates memory and copies the data content.
  157. static TBlob CopySingleThreaded(const void* data, size_t length);
  158. /// Creates a new blob with a multi-threaded (atomic) refcounter. Dynamically allocates memory and copies the data content.
  159. static TBlob Copy(const void* data, size_t length);
  160. /// Creates a blob which doesn't own data. No refcounter, no memory allocation, no data copy.
  161. static TBlob NoCopy(const void* data, size_t length);
  162. /// Creates a blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
  163. static TBlob FromFileSingleThreaded(const TString& path, EMappingMode);
  164. /// Creates a blob with a multi-threaded (atomic) refcounter. It maps the file on the path as data.
  165. static TBlob FromFile(const TString& path, EMappingMode);
  166. /// Creates a blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
  167. static TBlob FromFileSingleThreaded(const TFile& file, EMappingMode);
  168. /// Creates a blob with a multi-threaded (atomic) refcounter. It maps the file on the path as data.
  169. static TBlob FromFile(const TFile& file, EMappingMode);
  170. /// Creates a blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
  171. static TBlob FromFileSingleThreaded(const TString& path);
  172. /// Creates a blob with a multi-threaded (atomic) refcounter. It maps the file on the path as data.
  173. static TBlob FromFile(const TString& path);
  174. /// Creates a blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
  175. static TBlob FromFileSingleThreaded(const TFile& file);
  176. /// Creates a blob with a multi-threaded (atomic) refcounter. It maps the file on the path as data.
  177. static TBlob FromFile(const TFile& file);
  178. // TODO: drop Precharged* functions.
  179. /// Creates a precharged blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
  180. static TBlob PrechargedFromFileSingleThreaded(const TString& path);
  181. /// Creates a precharged blob with a multi-threaded (atomic) refcounter. It maps the file on the path as data.
  182. static TBlob PrechargedFromFile(const TString& path);
  183. /// Creates a precharged blob with a single-threaded (non atomic) refcounter. It maps the file content as data.
  184. static TBlob PrechargedFromFileSingleThreaded(const TFile& file);
  185. /// Creates a precharged blob with a multi-threaded (atomic) refcounter. It maps the file content as data.
  186. static TBlob PrechargedFromFile(const TFile& file);
  187. /// Creates a locked blob with a single-threaded (non atomic) refcounter. It maps the file on the path as data.
  188. static TBlob LockedFromFileSingleThreaded(const TString& path);
  189. /// Creates a locked blob with a multi-threaded (atomic) refcounter. It maps the file on the path as data.
  190. static TBlob LockedFromFile(const TString& path);
  191. /// Creates a locked blob with a single-threaded (non atomic) refcounter. It maps the file content as data.
  192. static TBlob LockedFromFileSingleThreaded(const TFile& file);
  193. /// Creates a locked blob with a multi-threaded (atomic) refcounter. It maps the file content as data.
  194. static TBlob LockedFromFile(const TFile& file);
  195. /// Creates a locked blob with a single-threaded (non atomic) refcounter from the mapped memory.
  196. static TBlob LockedFromMemoryMapSingleThreaded(const TMemoryMap& map, ui64 offset, size_t length);
  197. /// Creates a locked blob with a multi-threaded (atomic) refcounter from the mapped memory.
  198. static TBlob LockedFromMemoryMap(const TMemoryMap& map, ui64 offset, size_t length);
  199. /// Creates a blob with a single-threaded (non atomic) refcounter from the mapped memory.
  200. static TBlob FromMemoryMapSingleThreaded(const TMemoryMap& map, ui64 offset, size_t length);
  201. /// Creates a blob with a multi-threaded (atomic) refcounter from the mapped memory.
  202. static TBlob FromMemoryMap(const TMemoryMap& map, ui64 offset, size_t length);
  203. /// Creates a blob with a single-threaded (non atomic) refcounter. Dynamically allocates memory and copies data from the file on the path using pread().
  204. static TBlob FromFileContentSingleThreaded(const TString& path);
  205. /// Creates a blob with a multi-threaded (atomic) refcounter. Dynamically allocates memory and copies data from the file on the path using pread().
  206. static TBlob FromFileContent(const TString& path);
  207. /// Creates a blob with a single-threaded (non atomic) refcounter. Dynamically allocates memory and copies data from the file using pread().
  208. static TBlob FromFileContentSingleThreaded(const TFile& file);
  209. /// Creates a blob with a multi-threaded (atomic) refcounter. Dynamically allocates memory and copies data from the file using pread().
  210. static TBlob FromFileContent(const TFile& file);
  211. /// 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().
  212. static TBlob FromFileContentSingleThreaded(const TFile& file, ui64 offset, size_t length);
  213. /// 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().
  214. static TBlob FromFileContent(const TFile& file, ui64 offset, size_t length);
  215. /// Creates a blob from the stream content with a single-threaded (non atomic) refcounter.
  216. static TBlob FromStreamSingleThreaded(IInputStream& in);
  217. /// Creates a blob from the stream content with a multi-threaded (atomic) refcounter.
  218. static TBlob FromStream(IInputStream& in);
  219. /// Creates a blob with a single-threaded (non atomic) refcounter. No memory allocation, no content copy.
  220. /// @details The input object becomes empty.
  221. static TBlob FromBufferSingleThreaded(TBuffer& in);
  222. /// Creates a blob with a multi-threaded (atomic) refcounter. No memory allocation, no content copy.
  223. /// @details The input object becomes empty.
  224. static TBlob FromBuffer(TBuffer& in);
  225. /// Creates a blob from TString with a single-threaded (non atomic) refcounter.
  226. static TBlob FromStringSingleThreaded(const TString& s);
  227. /// Creates a blob from TString with a single-threaded (non atomic) refcounter. Doesn't copy its content.
  228. static TBlob FromStringSingleThreaded(TString&& s);
  229. /// Creates a blob from TString with a multi-threaded (atomic) refcounter.
  230. static TBlob FromString(const TString& s);
  231. /// Creates a blob from TString with a multi-threaded (atomic) refcounter. Doesn't copy its content.
  232. static TBlob FromString(TString&& s);
  233. private:
  234. inline void Ref() noexcept {
  235. if (S_.Base) {
  236. S_.Base->Ref();
  237. }
  238. }
  239. inline void UnRef() noexcept {
  240. if (S_.Base) {
  241. S_.Base->UnRef();
  242. }
  243. }
  244. private:
  245. TStorage S_;
  246. };
  247. /// @}