common.h 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340
  1. #pragma once
  2. ///
  3. /// @file yt/cpp/mapreduce/interface/common.h
  4. ///
  5. /// Header containing miscellaneous structs and classes used in library.
  6. #include "fwd.h"
  7. #include <library/cpp/type_info/type_info.h>
  8. #include <library/cpp/yson/node/node.h>
  9. #include <util/generic/guid.h>
  10. #include <util/generic/map.h>
  11. #include <util/generic/maybe.h>
  12. #include <util/generic/ptr.h>
  13. #include <util/system/type_name.h>
  14. #include <util/generic/vector.h>
  15. #include <google/protobuf/message.h>
  16. #include <initializer_list>
  17. #include <type_traits>
  18. namespace NYT {
  19. ////////////////////////////////////////////////////////////////////////////////
  20. /// @cond Doxygen_Suppress
  21. #define FLUENT_FIELD(type, name) \
  22. type name##_; \
  23. TSelf& name(const type& value) \
  24. { \
  25. name##_ = value; \
  26. return static_cast<TSelf&>(*this); \
  27. } \
  28. static_assert(true)
  29. #define FLUENT_FIELD_ENCAPSULATED(type, name) \
  30. private: \
  31. type name##_; \
  32. public: \
  33. TSelf& name(const type& value) & \
  34. { \
  35. name##_ = value; \
  36. return static_cast<TSelf&>(*this); \
  37. } \
  38. TSelf name(const type& value) && \
  39. { \
  40. name##_ = value; \
  41. return static_cast<TSelf&>(*this); \
  42. } \
  43. const type& name() const & \
  44. { \
  45. return name##_; \
  46. } \
  47. type name() && \
  48. { \
  49. return name##_; \
  50. } \
  51. static_assert(true)
  52. #define FLUENT_FIELD_OPTION(type, name) \
  53. TMaybe<type> name##_; \
  54. TSelf& name(const type& value) \
  55. { \
  56. name##_ = value; \
  57. return static_cast<TSelf&>(*this); \
  58. } \
  59. static_assert(true)
  60. #define FLUENT_FIELD_OPTION_ENCAPSULATED(type, name) \
  61. private: \
  62. TMaybe<type> name##_; \
  63. public: \
  64. TSelf& name(const type& value) & \
  65. { \
  66. name##_ = value; \
  67. return static_cast<TSelf&>(*this); \
  68. } \
  69. TSelf name(const type& value) && \
  70. { \
  71. name##_ = value; \
  72. return static_cast<TSelf&>(*this); \
  73. } \
  74. TSelf& Reset##name() & \
  75. { \
  76. name##_ = Nothing(); \
  77. return static_cast<TSelf&>(*this); \
  78. } \
  79. TSelf Reset##name() && \
  80. { \
  81. name##_ = Nothing(); \
  82. return static_cast<TSelf&>(*this); \
  83. } \
  84. const TMaybe<type>& name() const& \
  85. { \
  86. return name##_; \
  87. } \
  88. TMaybe<type> name() && \
  89. { \
  90. return name##_; \
  91. } \
  92. static_assert(true)
  93. #define FLUENT_FIELD_DEFAULT(type, name, defaultValue) \
  94. type name##_ = defaultValue; \
  95. TSelf& name(const type& value) \
  96. { \
  97. name##_ = value; \
  98. return static_cast<TSelf&>(*this); \
  99. } \
  100. static_assert(true)
  101. #define FLUENT_FIELD_DEFAULT_ENCAPSULATED(type, name, defaultValue) \
  102. private: \
  103. type name##_ = defaultValue; \
  104. public: \
  105. TSelf& name(const type& value) & \
  106. { \
  107. name##_ = value; \
  108. return static_cast<TSelf&>(*this); \
  109. } \
  110. TSelf name(const type& value) && \
  111. { \
  112. name##_ = value; \
  113. return static_cast<TSelf&>(*this); \
  114. } \
  115. const type& name() const & \
  116. { \
  117. return name##_; \
  118. } \
  119. type name() && \
  120. { \
  121. return name##_; \
  122. } \
  123. static_assert(true)
  124. #define FLUENT_VECTOR_FIELD(type, name) \
  125. TVector<type> name##s_; \
  126. TSelf& Add##name(const type& value) \
  127. { \
  128. name##s_.push_back(value); \
  129. return static_cast<TSelf&>(*this);\
  130. } \
  131. TSelf& name##s(TVector<type> values) \
  132. { \
  133. name##s_ = std::move(values); \
  134. return static_cast<TSelf&>(*this);\
  135. } \
  136. static_assert(true)
  137. #define FLUENT_OPTIONAL_VECTOR_FIELD_ENCAPSULATED(type, name) \
  138. private: \
  139. TMaybe<TVector<type>> name##s_; \
  140. public: \
  141. const TMaybe<TVector<type>>& name##s() const & { \
  142. return name##s_; \
  143. } \
  144. TMaybe<TVector<type>>& name##s() & { \
  145. return name##s_; \
  146. } \
  147. TMaybe<TVector<type>> name##s() && { \
  148. return std::move(name##s_); \
  149. } \
  150. TSelf& Add##name(const type& value) & \
  151. { \
  152. if (name##s_.Empty()) { \
  153. name##s_.ConstructInPlace(); \
  154. } \
  155. name##s_->push_back(value); \
  156. return static_cast<TSelf&>(*this);\
  157. } \
  158. TSelf Add##name(const type& value) && \
  159. { \
  160. if (name##s_.Empty()) { \
  161. name##s_.ConstructInPlace(); \
  162. } \
  163. name##s_->push_back(value); \
  164. return static_cast<TSelf&&>(*this);\
  165. } \
  166. TSelf& name##s(TVector<type> values) & \
  167. { \
  168. name##s_ = std::move(values); \
  169. return static_cast<TSelf&>(*this);\
  170. } \
  171. TSelf name##s(TVector<type> values) && \
  172. { \
  173. name##s_ = std::move(values); \
  174. return static_cast<TSelf&&>(*this);\
  175. } \
  176. TSelf& name##s(TNothing) & \
  177. { \
  178. name##s_ = Nothing(); \
  179. return static_cast<TSelf&>(*this);\
  180. } \
  181. TSelf name##s(TNothing) && \
  182. { \
  183. name##s_ = Nothing(); \
  184. return static_cast<TSelf&&>(*this);\
  185. } \
  186. TSelf& Reset##name##s() & \
  187. { \
  188. name##s_ = Nothing(); \
  189. return static_cast<TSelf&>(*this);\
  190. } \
  191. TSelf Reset##name##s() && \
  192. { \
  193. name##s_ = Nothing(); \
  194. return static_cast<TSelf&&>(*this);\
  195. } \
  196. static_assert(true)
  197. #define FLUENT_VECTOR_FIELD_ENCAPSULATED(type, name) \
  198. private: \
  199. TVector<type> name##s_; \
  200. public: \
  201. TSelf& Add##name(const type& value) & \
  202. { \
  203. name##s_.push_back(value); \
  204. return static_cast<TSelf&>(*this);\
  205. } \
  206. TSelf Add##name(const type& value) && \
  207. { \
  208. name##s_.push_back(value); \
  209. return static_cast<TSelf&>(*this);\
  210. } \
  211. TSelf& name##s(TVector<type> value) & \
  212. { \
  213. name##s_ = std::move(value); \
  214. return static_cast<TSelf&>(*this);\
  215. } \
  216. TSelf name##s(TVector<type> value) && \
  217. { \
  218. name##s_ = std::move(value); \
  219. return static_cast<TSelf&>(*this);\
  220. } \
  221. const TVector<type>& name##s() const & \
  222. { \
  223. return name##s_; \
  224. } \
  225. TVector<type> name##s() && \
  226. { \
  227. return name##s_; \
  228. } \
  229. static_assert(true)
  230. #define FLUENT_MAP_FIELD(keytype, valuetype, name) \
  231. TMap<keytype,valuetype> name##_; \
  232. TSelf& Add##name(const keytype& key, const valuetype& value) \
  233. { \
  234. name##_.emplace(key, value); \
  235. return static_cast<TSelf&>(*this);\
  236. } \
  237. static_assert(true)
  238. /// @endcond
  239. ////////////////////////////////////////////////////////////////////////////////
  240. ///
  241. /// @brief Convenience class that keeps sequence of items.
  242. ///
  243. /// Designed to be used as function parameter.
  244. ///
  245. /// Users of such function can then pass:
  246. /// - single item,
  247. /// - initializer list of items,
  248. /// - vector of items;
  249. /// as argument to this function.
  250. ///
  251. /// Example:
  252. /// ```
  253. /// void Foo(const TOneOrMany<int>& arg);
  254. /// ...
  255. /// Foo(1); // ok
  256. /// Foo({1, 2, 3}); // ok
  257. /// ```
  258. template <class T, class TDerived>
  259. struct TOneOrMany
  260. {
  261. /// @cond Doxygen_Suppress
  262. using TSelf = std::conditional_t<std::is_void_v<TDerived>, TOneOrMany, TDerived>;
  263. /// @endcond
  264. /// Initialize with empty sequence.
  265. TOneOrMany() = default;
  266. // Initialize from initializer list.
  267. template<class U>
  268. TOneOrMany(std::initializer_list<U> il)
  269. {
  270. Parts_.assign(il.begin(), il.end());
  271. }
  272. /// Put arguments to sequence
  273. template <class U, class... TArgs>
  274. requires std::is_convertible_v<U, T>
  275. TOneOrMany(U&& arg, TArgs&&... args)
  276. {
  277. Add(arg, std::forward<TArgs>(args)...);
  278. }
  279. /// Initialize from vector.
  280. TOneOrMany(TVector<T> args)
  281. : Parts_(std::move(args))
  282. { }
  283. /// @brief Order is defined the same way as in TVector
  284. bool operator==(const TOneOrMany& rhs) const
  285. {
  286. // N.B. We would like to make this method to be `= default`,
  287. // but this breaks MSVC compiler for the cases when T doesn't
  288. // support comparison.
  289. return Parts_ == rhs.Parts_;
  290. }
  291. ///
  292. /// @{
  293. ///
  294. /// @brief Add all arguments to sequence
  295. template <class U, class... TArgs>
  296. requires std::is_convertible_v<U, T>
  297. TSelf& Add(U&& part, TArgs&&... args) &
  298. {
  299. Parts_.push_back(std::forward<U>(part));
  300. if constexpr (sizeof...(args) > 0) {
  301. [[maybe_unused]] int dummy[sizeof...(args)] = {(Parts_.push_back(std::forward<TArgs>(args)), 0) ... };
  302. }
  303. return static_cast<TSelf&>(*this);
  304. }
  305. template <class U, class... TArgs>
  306. requires std::is_convertible_v<U, T>
  307. TSelf Add(U&& part, TArgs&&... args) &&
  308. {
  309. return std::move(Add(std::forward<U>(part), std::forward<TArgs>(args)...));
  310. }
  311. /// @}
  312. /// Content of sequence.
  313. TVector<T> Parts_;
  314. };
  315. ////////////////////////////////////////////////////////////////////////////////
  316. ///
  317. /// @brief Type of the value that can occur in YT table.
  318. ///
  319. /// @ref NYT::TTableSchema
  320. /// https://ytsaurus.tech/docs/en/user-guide/storage/data-types
  321. enum EValueType : int
  322. {
  323. /// Int64, signed integer of 64 bits.
  324. VT_INT64,
  325. /// Uint64, unsigned integer of 64 bits.
  326. VT_UINT64,
  327. /// Double, floating point number of double precision (64 bits).
  328. VT_DOUBLE,
  329. /// Boolean, `true` or `false`.
  330. VT_BOOLEAN,
  331. /// String, arbitrary byte sequence.
  332. VT_STRING,
  333. /// Any, arbitrary yson document.
  334. VT_ANY,
  335. /// Int8, signed integer of 8 bits.
  336. VT_INT8,
  337. /// Int16, signed integer of 16 bits.
  338. VT_INT16,
  339. /// Int32, signed integer of 32 bits.
  340. VT_INT32,
  341. /// Uint8, unsigned integer of 8 bits.
  342. VT_UINT8,
  343. /// Uint16, unsigned integer of 16 bits.
  344. VT_UINT16,
  345. /// Uint32, unsigned integer of 32 bits.
  346. VT_UINT32,
  347. /// Utf8, byte sequence that is valid utf8.
  348. VT_UTF8,
  349. /// Null, absence of value (almost never used in schemas)
  350. VT_NULL,
  351. /// Void, absence of value (almost never used in schemas) the difference between null, and void is yql-specific.
  352. VT_VOID,
  353. /// Date, number of days since Unix epoch (unsigned)
  354. VT_DATE,
  355. /// Datetime, number of seconds since Unix epoch (unsigned)
  356. VT_DATETIME,
  357. /// Timestamp, number of milliseconds since Unix epoch (unsigned)
  358. VT_TIMESTAMP,
  359. /// Interval, difference between two timestamps (signed)
  360. VT_INTERVAL,
  361. /// Float, floating point number (32 bits)
  362. VT_FLOAT,
  363. /// Json, sequence of bytes that is valid json.
  364. VT_JSON,
  365. // Date32, number of days shifted from Unix epoch, which is 0 (signed)
  366. VT_DATE32,
  367. // Datetime64, number of seconds shifted from Unix epoch, which is 0 (signed)
  368. VT_DATETIME64,
  369. // Timestamp64, number of milliseconds shifted from Unix epoch, which is 0 (signed)
  370. VT_TIMESTAMP64,
  371. // Interval64, difference between two timestamps64 (signed)
  372. VT_INTERVAL64,
  373. // Universally unique identifier according to RFC-4122.
  374. VT_UUID,
  375. };
  376. ///
  377. /// @brief Sort order.
  378. ///
  379. /// @ref NYT::TTableSchema
  380. enum ESortOrder : int
  381. {
  382. /// Ascending sort order.
  383. SO_ASCENDING /* "ascending" */,
  384. /// Descending sort order.
  385. SO_DESCENDING /* "descending" */,
  386. };
  387. ///
  388. /// @brief Value of "optimize_for" attribute.
  389. ///
  390. /// @ref NYT::TRichYPath
  391. enum EOptimizeForAttr : i8
  392. {
  393. /// Optimize for scan
  394. OF_SCAN_ATTR /* "scan" */,
  395. /// Optimize for lookup
  396. OF_LOOKUP_ATTR /* "lookup" */,
  397. };
  398. ///
  399. /// @brief Value of "erasure_codec" attribute.
  400. ///
  401. /// @ref NYT::TRichYPath
  402. enum EErasureCodecAttr : i8
  403. {
  404. /// @cond Doxygen_Suppress
  405. EC_NONE_ATTR /* "none" */,
  406. EC_REED_SOLOMON_6_3_ATTR /* "reed_solomon_6_3" */,
  407. EC_LRC_12_2_2_ATTR /* "lrc_12_2_2" */,
  408. EC_ISA_LRC_12_2_2_ATTR /* "isa_lrc_12_2_2" */,
  409. /// @endcond
  410. };
  411. ///
  412. /// @brief Value of "schema_modification" attribute.
  413. ///
  414. /// @ref NYT::TRichYPath
  415. enum ESchemaModificationAttr : i8
  416. {
  417. SM_NONE_ATTR /* "none" */,
  418. SM_UNVERSIONED_UPDATE /* "unversioned_update" */,
  419. };
  420. ////////////////////////////////////////////////////////////////////////////////
  421. ///
  422. /// @brief Table key column description.
  423. ///
  424. /// The description includes column name and sort order.
  425. ///
  426. /// @anchor TSortOrder_backward_compatibility
  427. /// @note
  428. /// Many functions that use `TSortOrder` as argument used to take `TString`
  429. /// (the only allowed sort order was "ascending" and user didn't have to specify it).
  430. /// @note
  431. /// This class is designed to provide backward compatibility for such code and therefore
  432. /// objects of this class can be constructed and assigned from TString-like objects only.
  433. ///
  434. /// @see NYT::TSortOperationSpec
  435. class TSortColumn
  436. {
  437. public:
  438. /// @cond Doxygen_Suppress
  439. using TSelf = TSortColumn;
  440. /// @endcond
  441. /// Column name
  442. FLUENT_FIELD_ENCAPSULATED(TString, Name);
  443. /// Sort order
  444. FLUENT_FIELD_DEFAULT_ENCAPSULATED(ESortOrder, SortOrder, ESortOrder::SO_ASCENDING);
  445. ///
  446. /// @{
  447. ///
  448. /// @brief Construct object from name and sort order
  449. ///
  450. /// Constructors are intentionally implicit so `TSortColumn` can be compatible with old code.
  451. /// @ref TSortOrder_backward_compatibility
  452. TSortColumn(TStringBuf name = {}, ESortOrder sortOrder = ESortOrder::SO_ASCENDING);
  453. TSortColumn(const TString& name, ESortOrder sortOrder = ESortOrder::SO_ASCENDING);
  454. TSortColumn(const char* name, ESortOrder sortOrder = ESortOrder::SO_ASCENDING);
  455. /// @}
  456. /// Check that sort order is ascending, throw exception otherwise.
  457. const TSortColumn& EnsureAscending() const;
  458. /// @brief Convert sort to yson representation as YT API expects it.
  459. TNode ToNode() const;
  460. /// @brief Comparison is default and checks both name and sort order.
  461. bool operator == (const TSortColumn& rhs) const = default;
  462. ///
  463. /// @{
  464. ///
  465. /// @brief Assign object from column name, and set sort order to `ascending`.
  466. ///
  467. /// This is backward compatibility methods.
  468. ///
  469. /// @ref TSortOrder_backward_compatibility
  470. TSortColumn& operator = (TStringBuf name);
  471. TSortColumn& operator = (const TString& name);
  472. TSortColumn& operator = (const char* name);
  473. /// @}
  474. bool operator == (const TStringBuf rhsName) const;
  475. bool operator == (const TString& rhsName) const;
  476. bool operator == (const char* rhsName) const;
  477. // Intentionally implicit conversions.
  478. operator TString() const;
  479. operator TStringBuf() const;
  480. operator std::string() const;
  481. Y_SAVELOAD_DEFINE(Name_, SortOrder_);
  482. };
  483. ///
  484. /// @brief List of @ref TSortColumn
  485. ///
  486. /// Contains a bunch of helper methods such as constructing from single object.
  487. class TSortColumns
  488. : public TOneOrMany<TSortColumn, TSortColumns>
  489. {
  490. public:
  491. using TOneOrMany<TSortColumn, TSortColumns>::TOneOrMany;
  492. /// Construct empty list.
  493. TSortColumns();
  494. ///
  495. /// @{
  496. ///
  497. /// @brief Construct list of ascending sort order columns by their names.
  498. ///
  499. /// Required for backward compatibility.
  500. ///
  501. /// @ref TSortOrder_backward_compatibility
  502. TSortColumns(const TVector<TString>& names);
  503. TSortColumns(const TColumnNames& names);
  504. /// @}
  505. ///
  506. /// @brief Implicit conversion to column list.
  507. ///
  508. /// If all columns has ascending sort order return list of their names.
  509. /// Throw exception otherwise.
  510. ///
  511. /// Required for backward compatibility.
  512. ///
  513. /// @ref TSortOrder_backward_compatibility
  514. operator TColumnNames() const;
  515. /// Make sure that all columns are of ascending sort order.
  516. const TSortColumns& EnsureAscending() const;
  517. /// Get list of column names.
  518. TVector<TString> GetNames() const;
  519. };
  520. ////////////////////////////////////////////////////////////////////////////////
  521. /// Helper function to create new style type from old style one.
  522. NTi::TTypePtr ToTypeV3(EValueType type, bool required);
  523. ///
  524. /// @brief Single column description
  525. ///
  526. /// Each field describing column has setter and getter.
  527. ///
  528. /// Example reading field:
  529. /// ```
  530. /// ... columnSchema.Name() ...
  531. /// ```
  532. ///
  533. /// Example setting field:
  534. /// ```
  535. /// columnSchema.Name("my-column").Type(VT_INT64); // set name and type
  536. /// ```
  537. ///
  538. /// @ref https://ytsaurus.tech/docs/en/user-guide/storage/static-schema
  539. class TColumnSchema
  540. {
  541. public:
  542. /// @cond Doxygen_Suppress
  543. using TSelf = TColumnSchema;
  544. /// @endcond
  545. ///
  546. /// @brief Construct empty column schemas
  547. ///
  548. /// @note
  549. /// Such schema cannot be used in schema as it it doesn't have name.
  550. TColumnSchema();
  551. ///
  552. /// @{
  553. ///
  554. /// @brief Copy and move constructors are default.
  555. TColumnSchema(const TColumnSchema&) = default;
  556. TColumnSchema& operator=(const TColumnSchema&) = default;
  557. /// @}
  558. FLUENT_FIELD_ENCAPSULATED(TString, Name);
  559. ///
  560. /// @brief Functions to work with type in old manner.
  561. ///
  562. /// @deprecated New code is recommended to work with types using @ref NTi::TTypePtr from type_info library.
  563. TColumnSchema& Type(EValueType type) &;
  564. TColumnSchema Type(EValueType type) &&;
  565. EValueType Type() const;
  566. /// @brief Set and get column type.
  567. /// @{
  568. TColumnSchema& Type(const NTi::TTypePtr& type) &;
  569. TColumnSchema Type(const NTi::TTypePtr& type) &&;
  570. TColumnSchema& TypeV3(const NTi::TTypePtr& type) &;
  571. TColumnSchema TypeV3(const NTi::TTypePtr& type) &&;
  572. NTi::TTypePtr TypeV3() const;
  573. /// @}
  574. /// Column sort order
  575. FLUENT_FIELD_OPTION_ENCAPSULATED(ESortOrder, SortOrder);
  576. ///
  577. /// @brief Lock group name
  578. ///
  579. /// @ref https://ytsaurus.tech/docs/en/user-guide/dynamic-tables/sorted-dynamic-tables#locking-rows
  580. FLUENT_FIELD_OPTION_ENCAPSULATED(TString, Lock);
  581. /// Expression defining column value
  582. FLUENT_FIELD_OPTION_ENCAPSULATED(TString, Expression);
  583. /// Aggregating function name
  584. FLUENT_FIELD_OPTION_ENCAPSULATED(TString, Aggregate);
  585. ///
  586. /// @brief Storage group name
  587. ///
  588. /// @ref https://ytsaurus.tech/docs/en/user-guide/storage/static-schema
  589. FLUENT_FIELD_OPTION_ENCAPSULATED(TString, Group);
  590. // StableName for renamed and deleted columns.
  591. FLUENT_FIELD_OPTION_ENCAPSULATED(TString, StableName);
  592. /// Deleted column
  593. FLUENT_FIELD_OPTION_ENCAPSULATED(bool, Deleted);
  594. ///
  595. /// @brief Column requiredness.
  596. ///
  597. /// Required columns doesn't accept NULL values.
  598. /// Usually if column is required it means that it has Optional<...> type
  599. bool Required() const;
  600. ///
  601. /// @{
  602. ///
  603. /// @brief Set type in old-style manner
  604. TColumnSchema& Type(EValueType type, bool required) &;
  605. TColumnSchema Type(EValueType type, bool required) &&;
  606. /// @}
  607. ///
  608. /// @{
  609. ///
  610. /// @brief Raw yson representation of column type
  611. /// @deprecated Prefer to use `TypeV3` methods.
  612. const TMaybe<TNode>& RawTypeV3() const;
  613. TColumnSchema& RawTypeV3(TNode rawTypeV3)&;
  614. TColumnSchema RawTypeV3(TNode rawTypeV3)&&;
  615. /// @}
  616. private:
  617. friend void Deserialize(TColumnSchema& columnSchema, const TNode& node);
  618. NTi::TTypePtr TypeV3_;
  619. TMaybe<TNode> RawTypeV3_;
  620. };
  621. /// Equality check checks all fields of column schema.
  622. bool operator==(const TColumnSchema& lhs, const TColumnSchema& rhs);
  623. ///
  624. /// @brief Description of table schema
  625. ///
  626. /// @see https://ytsaurus.tech/docs/en/user-guide/storage/static-schema
  627. class TTableSchema
  628. {
  629. public:
  630. /// @cond Doxygen_Suppress
  631. using TSelf = TTableSchema;
  632. /// @endcond
  633. /// Column schema
  634. FLUENT_VECTOR_FIELD_ENCAPSULATED(TColumnSchema, Column);
  635. ///
  636. /// @brief Strictness of the schema
  637. ///
  638. /// Strict schemas are not allowed to have columns not described in schema.
  639. /// Nonstrict schemas are allowed to have such columns, all such missing columns are assumed to have
  640. /// type any (or optional<yson> in type_v3 terminology).
  641. FLUENT_FIELD_DEFAULT_ENCAPSULATED(bool, Strict, true);
  642. ///
  643. /// @brief Whether keys are unique
  644. ///
  645. /// This flag can be set only for schemas that have sorted columns.
  646. /// If flag is set table cannot have multiple rows with same key.
  647. FLUENT_FIELD_DEFAULT_ENCAPSULATED(bool, UniqueKeys, false);
  648. /// Get modifiable column list
  649. TVector<TColumnSchema>& MutableColumns();
  650. /// Check if schema has any described column
  651. [[nodiscard]] bool Empty() const;
  652. /// Add column
  653. TTableSchema& AddColumn(const TString& name, const NTi::TTypePtr& type, ESortOrder sortOrder) &;
  654. /// @copydoc NYT::TTableSchema::AddColumn(const TString&, const NTi::TTypePtr&, ESortOrder)&;
  655. TTableSchema AddColumn(const TString& name, const NTi::TTypePtr& type, ESortOrder sortOrder) &&;
  656. /// @copydoc NYT::TTableSchema::AddColumn(const TString&, const NTi::TTypePtr&, ESortOrder)&;
  657. TTableSchema& AddColumn(const TString& name, const NTi::TTypePtr& type) &;
  658. /// @copydoc NYT::TTableSchema::AddColumn(const TString&, const NTi::TTypePtr&, ESortOrder)&;
  659. TTableSchema AddColumn(const TString& name, const NTi::TTypePtr& type) &&;
  660. /// Add optional column of specified type
  661. TTableSchema& AddColumn(const TString& name, EValueType type, ESortOrder sortOrder) &;
  662. /// @copydoc NYT::TTableSchema::AddColumn(const TString&, EValueType, ESortOrder)&;
  663. TTableSchema AddColumn(const TString& name, EValueType type, ESortOrder sortOrder) &&;
  664. /// @copydoc NYT::TTableSchema::AddColumn(const TString&, EValueType, ESortOrder)&;
  665. TTableSchema& AddColumn(const TString& name, EValueType type) &;
  666. /// @copydoc NYT::TTableSchema::AddColumn(const TString&, EValueType, ESortOrder)&;
  667. TTableSchema AddColumn(const TString& name, EValueType type) &&;
  668. ///
  669. /// @brief Make table schema sorted by specified columns
  670. ///
  671. /// Resets old key columns if any
  672. TTableSchema& SortBy(const TSortColumns& columns) &;
  673. /// @copydoc NYT::TTableSchema::SortBy(const TSortColumns&)&;
  674. TTableSchema SortBy(const TSortColumns& columns) &&;
  675. /// Get yson description of table schema
  676. [[nodiscard]] TNode ToNode() const;
  677. /// Parse schema from yson node
  678. static NYT::TTableSchema FromNode(const TNode& node);
  679. friend void Deserialize(TTableSchema& tableSchema, const TNode& node);
  680. };
  681. /// Check for equality of all columns and all schema attributes
  682. bool operator==(const TTableSchema& lhs, const TTableSchema& rhs);
  683. // Pretty printer for unittests
  684. void PrintTo(const TTableSchema& schema, std::ostream* out);
  685. /// Create table schema by protobuf message descriptor
  686. TTableSchema CreateTableSchema(
  687. const ::google::protobuf::Descriptor& messageDescriptor,
  688. const TSortColumns& sortColumns = TSortColumns(),
  689. bool keepFieldsWithoutExtension = true);
  690. /// Create table schema by protobuf message type
  691. template <class TProtoType, typename = std::enable_if_t<std::is_base_of_v<::google::protobuf::Message, TProtoType>>>
  692. inline TTableSchema CreateTableSchema(
  693. const TSortColumns& sortColumns = TSortColumns(),
  694. bool keepFieldsWithoutExtension = true)
  695. {
  696. static_assert(
  697. std::is_base_of_v<::google::protobuf::Message, TProtoType>,
  698. "Template argument must be derived from ::google::protobuf::Message");
  699. return CreateTableSchema(
  700. *TProtoType::descriptor(),
  701. sortColumns,
  702. keepFieldsWithoutExtension);
  703. }
  704. ///
  705. /// @brief Create strict table schema from `struct` type.
  706. ///
  707. /// Names and types of columns are taken from struct member names and types.
  708. /// `Strict` flag is set to true, all other attribute of schema and columns
  709. /// are left with default values
  710. TTableSchema CreateTableSchema(NTi::TTypePtr type);
  711. ////////////////////////////////////////////////////////////////////////////////
  712. ///
  713. /// @brief Enumeration describing comparison operation used in key bound.
  714. ///
  715. /// ERelation is a part of @ref NYT::TKeyBound that can be used as
  716. /// lower or upper key limit in @ref TReadLimit.
  717. ///
  718. /// Relations `Less` and `LessOrEqual` are for upper limit and
  719. /// relations `Greater` and `GreaterOrEqual` are for lower limit.
  720. ///
  721. /// It is a error to use relation in the limit of wrong kind.
  722. ///
  723. /// @see https://ytsaurus.tech/docs/en/user-guide/storage/ypath#rich_ypath
  724. enum class ERelation
  725. {
  726. ///
  727. /// @brief Relation "less"
  728. ///
  729. /// Specifies range of keys that are before specified key.
  730. /// Can only be used in upper limit.
  731. Less /* "<" */,
  732. ///
  733. /// @brief Relation "less or equal"
  734. ///
  735. /// Specifies range of keys that are before or equal specified key.
  736. /// Can only be used in upper limit.
  737. LessOrEqual /* "<=" */,
  738. ///
  739. /// @brief Relation "greater"
  740. ///
  741. /// Specifies range of keys that are after specified key.
  742. /// Can only be used in lower limit.
  743. Greater /* ">" */,
  744. ///
  745. /// @brief Relation "greater or equal"
  746. ///
  747. /// Specifies range of keys that are after or equal than specified key.
  748. /// Can only be used in lower limit.
  749. GreaterOrEqual /* ">=" */,
  750. };
  751. ///
  752. /// @brief Key with relation specifying interval of keys in lower or upper limit of @ref NYT::TReadRange
  753. ///
  754. /// @see https://ytsaurus.tech/docs/en/user-guide/common/ypath#rich_ypath
  755. struct TKeyBound
  756. {
  757. /// @cond Doxygen_Suppress
  758. using TSelf = TKeyBound;
  759. explicit TKeyBound(ERelation relation = ERelation::Less, TKey key = TKey{});
  760. FLUENT_FIELD_DEFAULT_ENCAPSULATED(ERelation, Relation, ERelation::Less);
  761. FLUENT_FIELD_DEFAULT_ENCAPSULATED(TKey, Key, TKey{});
  762. /// @endcond
  763. };
  764. ///
  765. /// @brief Description of the read limit.
  766. ///
  767. /// It is actually a variant and must store exactly one field.
  768. ///
  769. /// @see https://ytsaurus.tech/docs/en/user-guide/common/ypath#rich_ypath
  770. struct TReadLimit
  771. {
  772. /// @cond Doxygen_Suppress
  773. using TSelf = TReadLimit;
  774. /// @endcond
  775. ///
  776. /// @brief KeyBound specifies table key and whether to include it
  777. ///
  778. /// It can be used in lower or upper limit when reading tables.
  779. FLUENT_FIELD_OPTION(TKeyBound, KeyBound);
  780. ///
  781. /// @brief Table key
  782. ///
  783. /// It can be used in exact, lower or upper limit when reading tables.
  784. FLUENT_FIELD_OPTION(TKey, Key);
  785. ///
  786. /// @brief Row index
  787. ///
  788. /// It can be used in exact, lower or upper limit when reading tables.
  789. FLUENT_FIELD_OPTION(i64, RowIndex);
  790. ///
  791. /// @brief File offset
  792. ///
  793. /// It can be used in lower or upper limit when reading files.
  794. FLUENT_FIELD_OPTION(i64, Offset);
  795. ///
  796. /// @brief Tablet index
  797. ///
  798. /// It can be used in lower or upper limit in dynamic table operations
  799. FLUENT_FIELD_OPTION(i64, TabletIndex);
  800. };
  801. ///
  802. /// @brief Range of a table or a file
  803. ///
  804. /// @see https://ytsaurus.tech/docs/en/user-guide/common/ypath#rich_ypath
  805. struct TReadRange
  806. {
  807. using TSelf = TReadRange;
  808. ///
  809. /// @brief Lower limit of the range
  810. ///
  811. /// It is usually inclusive (except when @ref NYT::TKeyBound with relation @ref NYT::ERelation::Greater is used).
  812. FLUENT_FIELD(TReadLimit, LowerLimit);
  813. ///
  814. /// @brief Lower limit of the range
  815. ///
  816. /// It is usually exclusive (except when @ref NYT::TKeyBound with relation @ref NYT::ERelation::LessOrEqual is used).
  817. FLUENT_FIELD(TReadLimit, UpperLimit);
  818. /// Exact key or row index.
  819. FLUENT_FIELD(TReadLimit, Exact);
  820. /// Create read range from row indexes.
  821. static TReadRange FromRowIndices(i64 lowerLimit, i64 upperLimit)
  822. {
  823. return TReadRange()
  824. .LowerLimit(TReadLimit().RowIndex(lowerLimit))
  825. .UpperLimit(TReadLimit().RowIndex(upperLimit));
  826. }
  827. /// Create read range from keys.
  828. static TReadRange FromKeys(const TKey& lowerKeyInclusive, const TKey& upperKeyExclusive)
  829. {
  830. return TReadRange()
  831. .LowerLimit(TReadLimit().Key(lowerKeyInclusive))
  832. .UpperLimit(TReadLimit().Key(upperKeyExclusive));
  833. }
  834. };
  835. ///
  836. /// @brief Path with additional attributes.
  837. ///
  838. /// Allows to specify additional attributes for path used in some operations.
  839. ///
  840. /// @see https://ytsaurus.tech/docs/en/user-guide/storage/ypath#rich_ypath
  841. struct TRichYPath
  842. {
  843. /// @cond Doxygen_Suppress
  844. using TSelf = TRichYPath;
  845. /// @endcond
  846. /// Path itself.
  847. FLUENT_FIELD(TYPath, Path);
  848. /// Specifies that path should be appended not overwritten
  849. FLUENT_FIELD_OPTION(bool, Append);
  850. /// @deprecated Deprecated attribute.
  851. FLUENT_FIELD_OPTION(bool, PartiallySorted);
  852. /// Specifies that path is expected to be sorted by these columns.
  853. FLUENT_FIELD(TSortColumns, SortedBy);
  854. /// Add range to read.
  855. TRichYPath& AddRange(TReadRange range)
  856. {
  857. if (!Ranges_) {
  858. Ranges_.ConstructInPlace();
  859. }
  860. Ranges_->push_back(std::move(range));
  861. return *this;
  862. }
  863. TRichYPath& ResetRanges()
  864. {
  865. Ranges_.Clear();
  866. return *this;
  867. }
  868. ///
  869. /// @{
  870. ///
  871. /// Return ranges to read.
  872. ///
  873. /// NOTE: Nothing (in TMaybe) and empty TVector are different ranges.
  874. /// Nothing represents universal range (reader reads all table rows).
  875. /// Empty TVector represents empty range (reader returns empty set of rows).
  876. const TMaybe<TVector<TReadRange>>& GetRanges() const
  877. {
  878. return Ranges_;
  879. }
  880. TMaybe<TVector<TReadRange>>& MutableRanges()
  881. {
  882. return Ranges_;
  883. }
  884. ///
  885. /// @{
  886. ///
  887. /// Get range view, that is convenient way to iterate through all ranges.
  888. TArrayRef<TReadRange> MutableRangesView()
  889. {
  890. if (Ranges_.Defined()) {
  891. return TArrayRef(Ranges_->data(), Ranges_->size());
  892. } else {
  893. return {};
  894. }
  895. }
  896. TArrayRef<const TReadRange> GetRangesView() const
  897. {
  898. if (Ranges_.Defined()) {
  899. return TArrayRef(Ranges_->data(), Ranges_->size());
  900. } else {
  901. return {};
  902. }
  903. }
  904. /// @}
  905. /// @{
  906. ///
  907. /// Get range by index.
  908. const TReadRange& GetRange(ssize_t i) const
  909. {
  910. return Ranges_.GetRef()[i];
  911. }
  912. TReadRange& MutableRange(ssize_t i)
  913. {
  914. return Ranges_.GetRef()[i];
  915. }
  916. /// @}
  917. ///
  918. /// @brief Specifies columns that should be read.
  919. ///
  920. /// If it's set to Nothing then all columns will be read.
  921. /// If empty TColumnNames is specified then each read row will be empty.
  922. FLUENT_FIELD_OPTION(TColumnNames, Columns);
  923. FLUENT_FIELD_OPTION(bool, Teleport);
  924. FLUENT_FIELD_OPTION(bool, Primary);
  925. FLUENT_FIELD_OPTION(bool, Foreign);
  926. FLUENT_FIELD_OPTION(i64, RowCountLimit);
  927. FLUENT_FIELD_OPTION(TString, FileName);
  928. /// Specifies original path to be shown in Web UI
  929. FLUENT_FIELD_OPTION(TYPath, OriginalPath);
  930. ///
  931. /// @brief Specifies that this path points to executable file
  932. ///
  933. /// Used in operation specs.
  934. FLUENT_FIELD_OPTION(bool, Executable);
  935. ///
  936. /// @brief Specify format to use when loading table.
  937. ///
  938. /// Used in operation specs.
  939. FLUENT_FIELD_OPTION(TNode, Format);
  940. /// @brief Specifies table schema that will be set on the path
  941. FLUENT_FIELD_OPTION(TTableSchema, Schema);
  942. /// Specifies compression codec that will be set on the path
  943. FLUENT_FIELD_OPTION(TString, CompressionCodec);
  944. /// Specifies erasure codec that will be set on the path
  945. FLUENT_FIELD_OPTION(EErasureCodecAttr, ErasureCodec);
  946. /// Specifies schema modification that will be set on the path
  947. FLUENT_FIELD_OPTION(ESchemaModificationAttr, SchemaModification);
  948. /// Specifies optimize_for attribute that will be set on the path
  949. FLUENT_FIELD_OPTION(EOptimizeForAttr, OptimizeFor);
  950. ///
  951. /// @brief Do not put file used in operation into node cache
  952. ///
  953. /// If BypassArtifactCache == true, file will be loaded into the job's sandbox bypassing the cache on the YT node.
  954. /// It helps jobs that use tmpfs to start faster,
  955. /// because files will be loaded into tmpfs directly bypassing disk cache
  956. FLUENT_FIELD_OPTION(bool, BypassArtifactCache);
  957. ///
  958. /// @brief Timestamp of dynamic table.
  959. ///
  960. /// NOTE: it is _not_ unix timestamp
  961. /// (instead it's transaction timestamp, that is more complex structure).
  962. FLUENT_FIELD_OPTION(i64, Timestamp);
  963. ///
  964. /// @brief Specify transaction that should be used to access this path.
  965. ///
  966. /// Allows to start cross-transactional operations.
  967. FLUENT_FIELD_OPTION(TTransactionId, TransactionId);
  968. ///
  969. /// @brief Wether to create operation output path.
  970. ///
  971. /// If set to `true` output path is created by YT server.
  972. /// If set to `false` output path is not created explicitly (and operation will fail if it doesn't exist)
  973. /// If attribute is not set output path is created by this library using explicit master call.
  974. FLUENT_FIELD_OPTION(bool, Create);
  975. using TRenameColumnsDescriptor = THashMap<TString, TString>;
  976. /// Specifies columnar mapping which will be applied to columns before transfer to job.
  977. FLUENT_FIELD_OPTION(TRenameColumnsDescriptor, RenameColumns);
  978. /// Specifies cluster for the YPath
  979. FLUENT_FIELD_OPTION(TString, Cluster);
  980. /// Create empty path with no attributes
  981. TRichYPath()
  982. { }
  983. ///
  984. /// @{
  985. ///
  986. /// @brief Create path from string
  987. TRichYPath(const char* path)
  988. : Path_(path)
  989. { }
  990. TRichYPath(const TYPath& path)
  991. : Path_(path)
  992. { }
  993. /// @}
  994. private:
  995. TMaybe<TVector<TReadRange>> Ranges_;
  996. };
  997. ///
  998. /// @ref Create copy of @ref NYT::TRichYPath with schema derived from proto message.
  999. ///
  1000. ///
  1001. template <typename TProtoType>
  1002. TRichYPath WithSchema(const TRichYPath& path, const TSortColumns& sortBy = TSortColumns())
  1003. {
  1004. static_assert(std::is_base_of_v<::google::protobuf::Message, TProtoType>, "TProtoType must be Protobuf message");
  1005. auto schemedPath = path;
  1006. if (!schemedPath.Schema_) {
  1007. schemedPath.Schema(CreateTableSchema<TProtoType>(sortBy));
  1008. }
  1009. return schemedPath;
  1010. }
  1011. ///
  1012. /// @brief Create copy of @ref NYT::TRichYPath with schema derived from TRowType if possible.
  1013. ///
  1014. /// If TRowType is protobuf message schema is derived from it and set to returned path.
  1015. /// Otherwise schema of original path is left unchanged (and probably unset).
  1016. template <typename TRowType>
  1017. TRichYPath MaybeWithSchema(const TRichYPath& path, const TSortColumns& sortBy = TSortColumns())
  1018. {
  1019. if constexpr (std::is_base_of_v<::google::protobuf::Message, TRowType>) {
  1020. return WithSchema<TRowType>(path, sortBy);
  1021. } else {
  1022. return path;
  1023. }
  1024. }
  1025. ///
  1026. /// @brief Get the list of ranges related to path in compatibility mode.
  1027. ///
  1028. /// - If path is missing ranges, empty list is returned.
  1029. /// - If path has associated range list and the list is not empty, function returns this list.
  1030. /// - If path has associated range list and this list is empty, exception is thrown.
  1031. ///
  1032. /// Before YT-17683 RichYPath didn't support empty range list and empty range actually meant universal range.
  1033. /// This function emulates this old behavior.
  1034. ///
  1035. /// @see https://st.yandex-team.ru/YT-17683
  1036. const TVector<TReadRange>& GetRangesCompat(const TRichYPath& path);
  1037. ////////////////////////////////////////////////////////////////////////////////
  1038. /// Statistics about table columns.
  1039. struct TTableColumnarStatistics
  1040. {
  1041. /// Total data weight for all chunks for each of requested columns.
  1042. THashMap<TString, i64> ColumnDataWeight;
  1043. /// Estimated number of unique elements for each column.
  1044. THashMap<TString, ui64> ColumnEstimatedUniqueCounts;
  1045. /// Total weight of all old chunks that don't keep columnar statistics.
  1046. i64 LegacyChunksDataWeight = 0;
  1047. /// Timestamps total weight (only for dynamic tables).
  1048. TMaybe<i64> TimestampTotalWeight;
  1049. };
  1050. ////////////////////////////////////////////////////////////////////////////////
  1051. /// Description of a partition.
  1052. struct TMultiTablePartition
  1053. {
  1054. struct TStatistics
  1055. {
  1056. i64 ChunkCount = 0;
  1057. i64 DataWeight = 0;
  1058. i64 RowCount = 0;
  1059. };
  1060. /// Ranges of input tables for this partition.
  1061. TVector<TRichYPath> TableRanges;
  1062. /// Aggregate statistics of all the table ranges in the partition.
  1063. TStatistics AggregateStatistics;
  1064. };
  1065. /// Table partitions from GetTablePartitions command.
  1066. struct TMultiTablePartitions
  1067. {
  1068. /// Disjoint partitions into which the input tables were divided.
  1069. TVector<TMultiTablePartition> Partitions;
  1070. };
  1071. ////////////////////////////////////////////////////////////////////////////////
  1072. ///
  1073. /// @brief Contains information about tablet
  1074. ///
  1075. /// @see NYT::IClient::GetTabletInfos
  1076. struct TTabletInfo
  1077. {
  1078. ///
  1079. /// @brief Indicates the total number of rows added to the tablet (including trimmed ones).
  1080. ///
  1081. /// Currently only provided for ordered tablets.
  1082. i64 TotalRowCount = 0;
  1083. ///
  1084. /// @brief Contains the number of front rows that are trimmed and are not guaranteed to be accessible.
  1085. ///
  1086. /// Only makes sense for ordered tablet.
  1087. i64 TrimmedRowCount = 0;
  1088. ///
  1089. /// @brief Tablet cell barrier timestamp, which lags behind the current timestamp
  1090. ///
  1091. /// It is guaranteed that all transactions with commit timestamp not exceeding the barrier are fully committed;
  1092. /// e.g. all their added rows are visible (and are included in @ref NYT::TTabletInfo::TotalRowCount).
  1093. /// Mostly makes sense for ordered tablets.
  1094. ui64 BarrierTimestamp;
  1095. };
  1096. ////////////////////////////////////////////////////////////////////////////////
  1097. /// List of attributes to retrieve in operations like @ref NYT::ICypressClient::Get
  1098. struct TAttributeFilter
  1099. {
  1100. /// @cond Doxygen_Suppress
  1101. using TSelf = TAttributeFilter;
  1102. /// @endcond
  1103. /// List of attributes.
  1104. FLUENT_VECTOR_FIELD(TString, Attribute);
  1105. };
  1106. ////////////////////////////////////////////////////////////////////////////////
  1107. ///
  1108. /// @brief Check if none of the fields of @ref NYT::TReadLimit is set.
  1109. ///
  1110. /// @return true if any field of readLimit is set and false otherwise.
  1111. bool IsTrivial(const TReadLimit& readLimit);
  1112. /// Convert yson node type to table schema type
  1113. EValueType NodeTypeToValueType(TNode::EType nodeType);
  1114. ////////////////////////////////////////////////////////////////////////////////
  1115. ///
  1116. /// @brief Enumeration for specifying how reading from master is performed.
  1117. ///
  1118. /// Used in operations like NYT::ICypressClient::Get
  1119. enum class EMasterReadKind : int
  1120. {
  1121. ///
  1122. /// @brief Reading from leader.
  1123. ///
  1124. /// Should almost never be used since it's expensive and for regular uses has no difference from
  1125. /// "follower" read.
  1126. Leader /* "leader" */,
  1127. /// @brief Reading from master follower (default).
  1128. Follower /* "follower" */,
  1129. Cache /* "cache" */,
  1130. MasterCache /* "master_cache" */,
  1131. };
  1132. ////////////////////////////////////////////////////////////////////////////////
  1133. /// @cond Doxygen_Suppress
  1134. namespace NDetail {
  1135. // MUST NOT BE USED BY CLIENTS
  1136. // TODO: we should use default GENERATE_ENUM_SERIALIZATION
  1137. TString ToString(EValueType type);
  1138. } // namespace NDetail
  1139. /// @endcond
  1140. ////////////////////////////////////////////////////////////////////////////////
  1141. } // namespace NYT