mkql_computation_node_holders.cpp 115 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606
  1. #include "mkql_computation_node_holders.h"
  2. #include "mkql_computation_node_pack.h"
  3. #include "mkql_custom_list.h"
  4. #include "mkql_value_builder.h"
  5. #include "presort.h"
  6. #include <yql/essentials/minikql/mkql_node_builder.h>
  7. #include <yql/essentials/minikql/mkql_utils.h>
  8. #include <yql/essentials/minikql/mkql_alloc.h>
  9. #include <yql/essentials/minikql/mkql_node_cast.h>
  10. #include <yql/essentials/minikql/mkql_string_util.h>
  11. #include <yql/essentials/public/udf/udf_value.h>
  12. #include <library/cpp/containers/stack_vector/stack_vec.h>
  13. #include <util/generic/singleton.h>
  14. namespace NKikimr {
  15. namespace NMiniKQL {
  16. namespace {
  17. class TValueDataHolder: public TComputationValue<TValueDataHolder> {
  18. public:
  19. TValueDataHolder(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& value)
  20. : TComputationValue(memInfo)
  21. , Value(std::move(value))
  22. {}
  23. private:
  24. const NUdf::TUnboxedValue Value;
  25. };
  26. class TDirectListHolder: public TComputationValue<TDirectListHolder> {
  27. public:
  28. class TIterator: public TComputationValue<TIterator> {
  29. public:
  30. TIterator(const TDirectListHolder* parent)
  31. : TComputationValue(parent->GetMemInfo())
  32. , Parent(const_cast<TDirectListHolder*>(parent))
  33. , Iterator(parent->Items)
  34. , AtStart(true)
  35. {
  36. }
  37. private:
  38. bool Skip() override {
  39. if (AtStart) {
  40. AtStart = false;
  41. } else {
  42. if (Iterator.AtEnd()) {
  43. return false;
  44. }
  45. Iterator.Next();
  46. }
  47. return !Iterator.AtEnd();
  48. }
  49. bool Next(NUdf::TUnboxedValue& value) override {
  50. if (!Skip())
  51. return false;
  52. value = Iterator.Current();
  53. return true;
  54. }
  55. const NUdf::TRefCountedPtr<TDirectListHolder> Parent;
  56. TDefaultListRepresentation::TIterator Iterator;
  57. bool AtStart;
  58. };
  59. class TDictIterator: public TComputationValue<TDictIterator> {
  60. public:
  61. TDictIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& iter)
  62. : TComputationValue(memInfo)
  63. , Iter(std::move(iter))
  64. , Index(Max<ui64>())
  65. {}
  66. private:
  67. bool Next(NUdf::TUnboxedValue& key) override {
  68. if (Iter.Skip()) {
  69. key = NUdf::TUnboxedValuePod(++Index);
  70. return true;
  71. }
  72. return false;
  73. }
  74. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
  75. if (Iter.Next(payload)) {
  76. key = NUdf::TUnboxedValuePod(++Index);
  77. return true;
  78. }
  79. return false;
  80. }
  81. bool Skip() override {
  82. if (Iter.Skip()) {
  83. ++Index;
  84. return true;
  85. }
  86. return false;
  87. }
  88. const NUdf::TUnboxedValue Iter;
  89. ui64 Index;
  90. };
  91. TDirectListHolder(TMemoryUsageInfo* memInfo, TDefaultListRepresentation&& items)
  92. : TComputationValue(memInfo)
  93. , Items(std::move(items))
  94. {}
  95. private:
  96. bool Contains(const NUdf::TUnboxedValuePod& key) const override {
  97. const ui64 index = key.Get<ui64>();
  98. return (index < GetListLength());
  99. }
  100. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
  101. const ui64 index = key.Get<ui64>();
  102. if (index >= GetListLength()) {
  103. return NUdf::TUnboxedValuePod();
  104. }
  105. return Items.GetItemByIndex(index).Release().MakeOptional();
  106. }
  107. NUdf::TUnboxedValue GetListIterator() const override {
  108. return NUdf::TUnboxedValuePod(new TIterator(this));
  109. }
  110. NUdf::TUnboxedValue GetKeysIterator() const override {
  111. return NUdf::TUnboxedValuePod(new TDictIterator(GetMemInfo(), GetListIterator()));
  112. }
  113. NUdf::TUnboxedValue GetDictIterator() const override {
  114. return NUdf::TUnboxedValuePod(new TDictIterator(GetMemInfo(), GetListIterator()));
  115. }
  116. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  117. return NUdf::TUnboxedValuePod(new TIterator(this));
  118. }
  119. bool HasFastListLength() const override {
  120. return true;
  121. }
  122. ui64 GetListLength() const override {
  123. return Items.GetLength();
  124. }
  125. ui64 GetEstimatedListLength() const override {
  126. return Items.GetLength();
  127. }
  128. bool HasListItems() const override {
  129. return Items.GetLength() != 0;
  130. }
  131. const NUdf::TOpaqueListRepresentation* GetListRepresentation() const override {
  132. return reinterpret_cast<const NUdf::TOpaqueListRepresentation*>(&Items);
  133. }
  134. NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const override {
  135. switch (Items.GetLength()) {
  136. case 0U: return builder.NewEmptyList().Release().AsBoxed();
  137. case 1U: return const_cast<TDirectListHolder*>(this);
  138. default: break;
  139. }
  140. TDefaultListRepresentation result;
  141. for (auto it = Items.GetReverseIterator(); !it.AtEnd(); it.Next()) {
  142. result = result.Append(NUdf::TUnboxedValue(it.Current()));
  143. }
  144. return new TDirectListHolder(GetMemInfo(), std::move(result));
  145. }
  146. NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
  147. if (count == 0)
  148. return const_cast<TDirectListHolder*>(this);
  149. if (count >= Items.GetLength())
  150. return builder.NewEmptyList().Release().AsBoxed();
  151. auto result = Items.SkipFromBegin(static_cast<size_t>(count));
  152. return new TDirectListHolder(GetMemInfo(), std::move(result));
  153. }
  154. NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
  155. if (count == 0)
  156. return builder.NewEmptyList().Release().AsBoxed();
  157. if (count >= Items.GetLength())
  158. return const_cast<TDirectListHolder*>(this);
  159. auto result = Items.SkipFromEnd(static_cast<size_t>(Items.GetLength() - count));
  160. return new TDirectListHolder(GetMemInfo(), std::move(result));
  161. }
  162. NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder& builder) const override {
  163. Y_UNUSED(builder);
  164. return const_cast<TDirectListHolder*>(this);
  165. }
  166. ui64 GetDictLength() const override {
  167. return GetListLength();
  168. }
  169. bool HasDictItems() const override {
  170. return Items.GetLength() != 0;
  171. }
  172. NUdf::TUnboxedValue GetElement(ui32 index) const final {
  173. return Items.GetItemByIndex(index);
  174. }
  175. const NUdf::TUnboxedValue* GetElements() const final {
  176. return Items.GetItems();
  177. }
  178. bool IsSortedDict() const override {
  179. return true;
  180. }
  181. TDefaultListRepresentation Items;
  182. };
  183. template <class TBaseVector>
  184. class TVectorHolderBase: public TComputationValue<TVectorHolderBase<TBaseVector>>, public TBaseVector {
  185. private:
  186. using TBaseValue = TComputationValue<TVectorHolderBase<TBaseVector>>;
  187. public:
  188. TVectorHolderBase(TMemoryUsageInfo* memInfo)
  189. : TBaseValue(memInfo)
  190. {
  191. }
  192. TVectorHolderBase(TMemoryUsageInfo* memInfo, TBaseVector&& vector)
  193. : TBaseValue(memInfo)
  194. , TBaseVector(std::move(vector)) {
  195. }
  196. ~TVectorHolderBase() {
  197. }
  198. private:
  199. class TValuesIterator: public TTemporaryComputationValue<TValuesIterator> {
  200. private:
  201. using TBase = TTemporaryComputationValue<TValuesIterator>;
  202. public:
  203. TValuesIterator(const TVectorHolderBase* parent)
  204. : TBase(parent->GetMemInfo())
  205. , Size(parent->size())
  206. , Parent(const_cast<TVectorHolderBase*>(parent)) {
  207. }
  208. private:
  209. bool Skip() final {
  210. return ++Current < Size;
  211. }
  212. bool Next(NUdf::TUnboxedValue& value) final {
  213. if (Size <= Current) {
  214. return false;
  215. }
  216. value = (*Parent)[Current];
  217. ++Current;
  218. return true;
  219. }
  220. const size_t Size;
  221. ui64 Current = 0;
  222. const NUdf::TRefCountedPtr<TVectorHolderBase> Parent;
  223. };
  224. class TDictIterator: public TTemporaryComputationValue<TDictIterator> {
  225. private:
  226. using TBase = TTemporaryComputationValue<TDictIterator>;
  227. public:
  228. TDictIterator(const TVectorHolderBase* parent)
  229. : TBase(parent->GetMemInfo())
  230. , Size(parent->size())
  231. , Parent(const_cast<TVectorHolderBase*>(parent)) {
  232. }
  233. private:
  234. bool Skip() final {
  235. return ++Current < Size;
  236. }
  237. bool Next(NUdf::TUnboxedValue& key) final {
  238. if (Current == Size) {
  239. return false;
  240. }
  241. key = NUdf::TUnboxedValuePod(Current);
  242. ++Current;
  243. return true;
  244. }
  245. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
  246. if (Current == Size) {
  247. return false;
  248. }
  249. key = NUdf::TUnboxedValuePod(Current);
  250. payload = (*Parent)[Current];
  251. ++Current;
  252. return true;
  253. }
  254. const size_t Size;
  255. ui64 Current = 0;
  256. const NUdf::TRefCountedPtr<TVectorHolderBase> Parent;
  257. };
  258. bool HasListItems() const final {
  259. return TBaseVector::size();
  260. }
  261. bool HasDictItems() const final {
  262. return TBaseVector::size();
  263. }
  264. bool HasFastListLength() const final {
  265. return true;
  266. }
  267. ui64 GetListLength() const final {
  268. return TBaseVector::size();
  269. }
  270. ui64 GetDictLength() const final {
  271. return TBaseVector::size();
  272. }
  273. ui64 GetEstimatedListLength() const final {
  274. return TBaseVector::size();
  275. }
  276. NUdf::TUnboxedValue GetListIterator() const final {
  277. return NUdf::TUnboxedValuePod(new TValuesIterator(this));
  278. }
  279. NUdf::TUnboxedValue GetDictIterator() const final {
  280. return NUdf::TUnboxedValuePod(new TDictIterator(this));
  281. }
  282. NUdf::TUnboxedValue GetPayloadsIterator() const final {
  283. return NUdf::TUnboxedValuePod(new TValuesIterator(this));
  284. }
  285. NUdf::TUnboxedValue GetKeysIterator() const final {
  286. return NUdf::TUnboxedValuePod(new TDictIterator(this));
  287. }
  288. NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder&) const final {
  289. if (1U >= TBaseVector::size()) {
  290. return const_cast<TVectorHolderBase*>(this);
  291. }
  292. TBaseVector copy(TBaseVector::rbegin(), TBaseVector::rend());
  293. return new TVectorHolderBase(TBaseValue::GetMemInfo(), std::move(copy));
  294. }
  295. void Push(const NUdf::TUnboxedValuePod& value) final {
  296. TBaseVector::emplace_back(value);
  297. }
  298. NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const final {
  299. if (!count)
  300. return const_cast<TVectorHolderBase*>(this);
  301. if (count >= TBaseVector::size())
  302. return builder.NewEmptyList().Release().AsBoxed();
  303. TBaseVector copy(TBaseVector::begin() + count, TBaseVector::end());
  304. return new TVectorHolderBase(TBaseValue::GetMemInfo(), std::move(copy));
  305. }
  306. NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const final {
  307. if (!count)
  308. return builder.NewEmptyList().Release().AsBoxed();
  309. if (count >= TBaseVector::size())
  310. return const_cast<TVectorHolderBase*>(this);
  311. TBaseVector copy(TBaseVector::begin(), TBaseVector::begin() + count);
  312. return new TVectorHolderBase(TBaseValue::GetMemInfo(), std::move(copy));
  313. }
  314. NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder&) const final {
  315. return const_cast<TVectorHolderBase*>(this);
  316. }
  317. bool Contains(const NUdf::TUnboxedValuePod& key) const final {
  318. return key.Get<ui64>() < TBaseVector::size();
  319. }
  320. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
  321. const auto index = key.Get<ui64>();
  322. return index < TBaseVector::size() ? TBaseVector::at(index).MakeOptional() : NUdf::TUnboxedValuePod();
  323. }
  324. const NUdf::TUnboxedValue* GetElements() const final {
  325. return TBaseVector::data();
  326. }
  327. bool IsSortedDict() const override {
  328. return true;
  329. }
  330. };
  331. class TVectorHolder: public TVectorHolderBase<TUnboxedValueVector> {
  332. private:
  333. using TBase = TVectorHolderBase<TUnboxedValueVector>;
  334. public:
  335. using TBase::TBase;
  336. };
  337. class TTemporaryVectorHolder: public TVectorHolderBase<TTemporaryUnboxedValueVector> {
  338. private:
  339. using TBase = TVectorHolderBase<TTemporaryUnboxedValueVector>;
  340. public:
  341. using TBase::TBase;
  342. };
  343. class TEmptyContainerHolder: public TComputationValue<TEmptyContainerHolder> {
  344. public:
  345. TEmptyContainerHolder(TMemoryUsageInfo* memInfo)
  346. : TComputationValue(memInfo), None()
  347. {}
  348. private:
  349. bool Contains(const NUdf::TUnboxedValuePod&) const override {
  350. return false;
  351. }
  352. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod&) const override {
  353. return None;
  354. }
  355. NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue&) override {
  356. return NUdf::EFetchStatus::Finish;
  357. }
  358. NUdf::TUnboxedValue GetListIterator() const override {
  359. return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
  360. }
  361. NUdf::TUnboxedValue GetDictIterator() const override {
  362. return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
  363. }
  364. NUdf::TUnboxedValue GetKeysIterator() const override {
  365. return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
  366. }
  367. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  368. return NUdf::TUnboxedValuePod(const_cast<TEmptyContainerHolder*>(this));
  369. }
  370. bool Skip() final {
  371. return false;
  372. }
  373. bool Next(NUdf::TUnboxedValue&) final {
  374. return false;
  375. }
  376. bool NextPair(NUdf::TUnboxedValue&, NUdf::TUnboxedValue&) final {
  377. return false;
  378. }
  379. const NUdf::TOpaqueListRepresentation* GetListRepresentation() const override {
  380. return reinterpret_cast<const NUdf::TOpaqueListRepresentation*>(&List);
  381. }
  382. bool HasFastListLength() const override {
  383. return true;
  384. }
  385. ui64 GetListLength() const override {
  386. return 0;
  387. }
  388. ui64 GetEstimatedListLength() const override {
  389. return 0;
  390. }
  391. bool HasListItems() const override {
  392. return false;
  393. }
  394. NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const override {
  395. Y_UNUSED(builder);
  396. return const_cast<TEmptyContainerHolder*>(this);
  397. }
  398. NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
  399. Y_UNUSED(builder);
  400. Y_UNUSED(count);
  401. return const_cast<TEmptyContainerHolder*>(this);
  402. }
  403. NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
  404. Y_UNUSED(builder);
  405. Y_UNUSED(count);
  406. return const_cast<TEmptyContainerHolder*>(this);
  407. }
  408. NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder& builder) const override {
  409. Y_UNUSED(builder);
  410. return const_cast<TEmptyContainerHolder*>(this);
  411. }
  412. ui64 GetDictLength() const override {
  413. return 0;
  414. }
  415. bool HasDictItems() const override {
  416. return false;
  417. }
  418. bool IsSortedDict() const override {
  419. return true;
  420. }
  421. const NUdf::TUnboxedValue* GetElements() const override {
  422. return &None;
  423. }
  424. const NUdf::TUnboxedValue None;
  425. const TDefaultListRepresentation List;
  426. };
  427. class TSortedSetHolder: public TComputationValue<TSortedSetHolder> {
  428. public:
  429. typedef TUnboxedValueVector TItems;
  430. template <bool NoSwap>
  431. class TIterator: public TComputationValue<TIterator<NoSwap>> {
  432. public:
  433. TIterator(const TSortedSetHolder* parent)
  434. : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
  435. , Parent(const_cast<TSortedSetHolder*>(parent))
  436. , Iterator(Parent->Items.begin())
  437. , AtStart(true)
  438. {
  439. }
  440. private:
  441. bool Skip() override {
  442. if (AtStart) {
  443. AtStart = false;
  444. } else {
  445. if (Iterator == Parent->Items.end())
  446. return false;
  447. ++Iterator;
  448. }
  449. return Iterator != Parent->Items.end();
  450. }
  451. bool Next(NUdf::TUnboxedValue& key) override {
  452. if (!Skip())
  453. return false;
  454. if (NoSwap) {
  455. key = *Iterator;
  456. if (Parent->Packer) {
  457. key = Parent->Packer->Decode(key.AsStringRef(), false, Parent->HolderFactory);
  458. }
  459. } else {
  460. key = NUdf::TUnboxedValuePod::Void();
  461. }
  462. return true;
  463. }
  464. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
  465. if (!Next(key))
  466. return false;
  467. if (NoSwap) {
  468. payload = NUdf::TUnboxedValuePod::Void();
  469. } else {
  470. payload = *Iterator;
  471. if (Parent->Packer) {
  472. payload = Parent->Packer->Decode(payload.AsStringRef(), false, Parent->HolderFactory);
  473. }
  474. }
  475. return true;
  476. }
  477. const NUdf::TRefCountedPtr<TSortedSetHolder> Parent;
  478. TItems::const_iterator Iterator;
  479. bool AtStart;
  480. };
  481. TSortedSetHolder(
  482. TMemoryUsageInfo* memInfo,
  483. TSortedSetFiller filler,
  484. const TKeyTypes& types,
  485. bool isTuple,
  486. EDictSortMode mode,
  487. bool eagerFill,
  488. TType* encodedType,
  489. const NUdf::ICompare* compare,
  490. const NUdf::IEquate* equate,
  491. const THolderFactory& holderFactory)
  492. : TComputationValue(memInfo)
  493. , Filler(filler)
  494. , Types(types)
  495. , IsTuple(isTuple)
  496. , Mode(mode)
  497. , Compare(compare)
  498. , Equate(equate)
  499. , IsBuilt(false)
  500. , HolderFactory(holderFactory)
  501. {
  502. if (encodedType) {
  503. Packer.emplace(encodedType);
  504. }
  505. if (eagerFill)
  506. LazyBuildDict();
  507. }
  508. ~TSortedSetHolder() {
  509. MKQL_MEM_RETURN(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
  510. }
  511. private:
  512. bool Contains(const NUdf::TUnboxedValuePod& key) const override {
  513. LazyBuildDict();
  514. NUdf::TUnboxedValue encodedKey;
  515. if (Packer) {
  516. encodedKey = MakeString(Packer->Encode(key, false));
  517. }
  518. return BinarySearch(Items.begin(), Items.end(), NUdf::TUnboxedValuePod(Packer ? encodedKey : key),
  519. TValueLess(Types, IsTuple, Compare));
  520. }
  521. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
  522. LazyBuildDict();
  523. NUdf::TUnboxedValue encodedKey;
  524. if (Packer) {
  525. encodedKey = MakeString(Packer->Encode(key, false));
  526. }
  527. const auto it = LowerBound(Items.begin(), Items.end(), NUdf::TUnboxedValuePod(Packer ? encodedKey : key), TValueLess(Types, IsTuple, Compare));
  528. if (it == Items.end() || !TValueEqual(Types, IsTuple, Equate)(*it, NUdf::TUnboxedValuePod(Packer ? encodedKey : key)))
  529. return NUdf::TUnboxedValuePod();
  530. return it->MakeOptional();
  531. }
  532. NUdf::TUnboxedValue GetKeysIterator() const override {
  533. LazyBuildDict();
  534. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  535. }
  536. NUdf::TUnboxedValue GetDictIterator() const override {
  537. LazyBuildDict();
  538. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  539. }
  540. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  541. LazyBuildDict();
  542. return NUdf::TUnboxedValuePod(new TIterator<false>(this));
  543. }
  544. ui64 GetDictLength() const override {
  545. LazyBuildDict();
  546. return Items.size();
  547. }
  548. bool HasDictItems() const override {
  549. LazyBuildDict();
  550. return !Items.empty();
  551. }
  552. void LazyBuildDict() const {
  553. if (IsBuilt)
  554. return;
  555. Filler(Items);
  556. Filler = TSortedSetFiller();
  557. switch (Mode) {
  558. case EDictSortMode::RequiresSorting:
  559. StableSort(Items.begin(), Items.end(), TValueLess(Types, IsTuple, Compare));
  560. Items.erase(Unique(Items.begin(), Items.end(), TValueEqual(Types, IsTuple, Equate)), Items.end());
  561. break;
  562. case EDictSortMode::SortedUniqueAscending:
  563. break;
  564. case EDictSortMode::SortedUniqueDescening:
  565. Reverse(Items.begin(), Items.end());
  566. break;
  567. default:
  568. Y_ABORT();
  569. }
  570. Y_DEBUG_ABORT_UNLESS(IsSortedUnique());
  571. IsBuilt = true;
  572. if (!Items.empty()) {
  573. MKQL_MEM_TAKE(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
  574. }
  575. }
  576. bool IsSortedUnique() const {
  577. TValueLess less(Types, IsTuple, Compare);
  578. for (size_t i = 1, e = Items.size(); i < e; ++i) {
  579. if (!less(Items[i - 1], Items[i]))
  580. return false;
  581. }
  582. return true;
  583. }
  584. bool IsSortedDict() const override {
  585. return true;
  586. }
  587. private:
  588. mutable TSortedSetFiller Filler;
  589. const TKeyTypes Types;
  590. const bool IsTuple;
  591. const EDictSortMode Mode;
  592. const NUdf::ICompare* Compare;
  593. const NUdf::IEquate* Equate;
  594. mutable bool IsBuilt;
  595. const THolderFactory& HolderFactory;
  596. mutable TItems Items;
  597. mutable std::optional<TGenericPresortEncoder> Packer;
  598. };
  599. class TSortedDictHolder: public TComputationValue<TSortedDictHolder> {
  600. public:
  601. typedef TKeyPayloadPairVector TItems;
  602. template <bool NoSwap>
  603. class TIterator: public TComputationValue<TIterator<NoSwap>> {
  604. public:
  605. TIterator(const TSortedDictHolder* parent)
  606. : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
  607. , Parent(const_cast<TSortedDictHolder*>(parent))
  608. , Iterator(Parent->Items.begin())
  609. , AtStart(true)
  610. {
  611. }
  612. private:
  613. bool Skip() override {
  614. if (AtStart) {
  615. AtStart = false;
  616. } else {
  617. if (Iterator == Parent->Items.end())
  618. return false;
  619. ++Iterator;
  620. }
  621. return Iterator != Parent->Items.end();
  622. }
  623. bool Next(NUdf::TUnboxedValue& key) override {
  624. if (!Skip())
  625. return false;
  626. if (NoSwap) {
  627. key = Iterator->first;
  628. if (Parent->Packer) {
  629. key = Parent->Packer->Decode(key.AsStringRef(), false, Parent->HolderFactory);
  630. }
  631. } else {
  632. key = Iterator->second;
  633. }
  634. return true;
  635. }
  636. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
  637. if (!Next(key))
  638. return false;
  639. if (NoSwap) {
  640. payload = Iterator->second;
  641. } else {
  642. payload = Iterator->first;
  643. if (Parent->Packer) {
  644. payload = Parent->Packer->Decode(payload.AsStringRef(), false, Parent->HolderFactory);
  645. }
  646. }
  647. return true;
  648. }
  649. const NUdf::TRefCountedPtr<TSortedDictHolder> Parent;
  650. TItems::const_iterator Iterator;
  651. bool AtStart;
  652. };
  653. TSortedDictHolder(
  654. TMemoryUsageInfo* memInfo,
  655. TSortedDictFiller filler,
  656. const TKeyTypes& types,
  657. bool isTuple,
  658. EDictSortMode mode,
  659. bool eagerFill,
  660. TType* encodedType,
  661. const NUdf::ICompare* compare,
  662. const NUdf::IEquate* equate,
  663. const THolderFactory& holderFactory)
  664. : TComputationValue(memInfo)
  665. , Filler(filler)
  666. , Types(types)
  667. , IsTuple(isTuple)
  668. , Mode(mode)
  669. , Compare(compare)
  670. , Equate(equate)
  671. , IsBuilt(false)
  672. , HolderFactory(holderFactory)
  673. {
  674. if (encodedType) {
  675. Packer.emplace(encodedType);
  676. }
  677. if (eagerFill)
  678. LazyBuildDict();
  679. }
  680. ~TSortedDictHolder() {
  681. MKQL_MEM_RETURN(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
  682. }
  683. private:
  684. bool Contains(const NUdf::TUnboxedValuePod& key) const override {
  685. LazyBuildDict();
  686. NUdf::TUnboxedValue encodedKey;
  687. if (Packer) {
  688. encodedKey = MakeString(Packer->Encode(key, false));
  689. }
  690. return BinarySearch(Items.begin(), Items.end(), TItems::value_type(NUdf::TUnboxedValuePod(Packer ? encodedKey : key), NUdf::TUnboxedValuePod()),
  691. TKeyPayloadPairLess(Types, IsTuple, Compare));
  692. }
  693. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
  694. LazyBuildDict();
  695. NUdf::TUnboxedValue encodedKey;
  696. if (Packer) {
  697. encodedKey = MakeString(Packer->Encode(key, false));
  698. }
  699. const auto it = LowerBound(Items.begin(), Items.end(), TItems::value_type(NUdf::TUnboxedValuePod(Packer ? encodedKey : key), NUdf::TUnboxedValue()), TKeyPayloadPairLess(Types, IsTuple, Compare));
  700. if (it == Items.end() || !TKeyPayloadPairEqual(Types, IsTuple, Equate)({it->first, it->second}, TKeyPayloadPair(NUdf::TUnboxedValuePod(Packer ? encodedKey : key), {})))
  701. return NUdf::TUnboxedValuePod();
  702. return it->second.MakeOptional();
  703. }
  704. NUdf::TUnboxedValue GetKeysIterator() const override {
  705. LazyBuildDict();
  706. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  707. }
  708. NUdf::TUnboxedValue GetDictIterator() const override {
  709. LazyBuildDict();
  710. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  711. }
  712. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  713. LazyBuildDict();
  714. return NUdf::TUnboxedValuePod(new TIterator<false>(this));
  715. }
  716. ui64 GetDictLength() const override {
  717. LazyBuildDict();
  718. return Items.size();
  719. }
  720. bool HasDictItems() const override {
  721. LazyBuildDict();
  722. return !Items.empty();
  723. }
  724. void LazyBuildDict() const {
  725. if (IsBuilt)
  726. return;
  727. Filler(Items);
  728. Filler = TSortedDictFiller();
  729. switch (Mode) {
  730. case EDictSortMode::RequiresSorting:
  731. StableSort(Items.begin(), Items.end(), TKeyPayloadPairLess(Types, IsTuple, Compare));
  732. Items.erase(Unique(Items.begin(), Items.end(), TKeyPayloadPairEqual(Types, IsTuple, Equate)), Items.end());
  733. break;
  734. case EDictSortMode::SortedUniqueAscending:
  735. break;
  736. case EDictSortMode::SortedUniqueDescening:
  737. Reverse(Items.begin(), Items.end());
  738. break;
  739. default:
  740. Y_ABORT();
  741. }
  742. Y_DEBUG_ABORT_UNLESS(IsSortedUnique());
  743. IsBuilt = true;
  744. if (!Items.empty()) {
  745. MKQL_MEM_TAKE(GetMemInfo(), &Items, Items.capacity() * sizeof(TItems::value_type));
  746. }
  747. }
  748. bool IsSortedUnique() const {
  749. TKeyPayloadPairLess less(Types, IsTuple, Compare);
  750. for (size_t i = 1, e = Items.size(); i < e; ++i) {
  751. if (!less(Items[i - 1], Items[i]))
  752. return false;
  753. }
  754. return true;
  755. }
  756. bool IsSortedDict() const override {
  757. return true;
  758. }
  759. private:
  760. mutable TSortedDictFiller Filler;
  761. const TKeyTypes Types;
  762. const bool IsTuple;
  763. const EDictSortMode Mode;
  764. const NUdf::ICompare* Compare;
  765. const NUdf::IEquate* Equate;
  766. mutable bool IsBuilt;
  767. const THolderFactory& HolderFactory;
  768. mutable TItems Items;
  769. mutable std::optional<TGenericPresortEncoder> Packer;
  770. };
  771. class THashedSetHolder : public TComputationValue<THashedSetHolder> {
  772. public:
  773. class TIterator : public TComputationValue<TIterator> {
  774. public:
  775. TIterator(const THashedSetHolder* parent)
  776. : TComputationValue(parent->GetMemInfo())
  777. , Parent(const_cast<THashedSetHolder*>(parent))
  778. , Iterator(Parent->Set.begin())
  779. , End(Parent->Set.end())
  780. , AtStart(true)
  781. {
  782. }
  783. private:
  784. bool Skip() override {
  785. if (AtStart) {
  786. AtStart = false;
  787. }
  788. else {
  789. if (Iterator == End) {
  790. return false;
  791. }
  792. ++Iterator;
  793. }
  794. return Iterator != End;
  795. }
  796. bool Next(NUdf::TUnboxedValue& key) override {
  797. if (!Skip())
  798. return false;
  799. key = *Iterator;
  800. if (Parent->Packer) {
  801. key = Parent->Packer->Unpack(key.AsStringRef(), Parent->HolderFactory);
  802. }
  803. return true;
  804. }
  805. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
  806. if (!Next(key))
  807. return false;
  808. payload = NUdf::TUnboxedValuePod::Void();
  809. return true;
  810. }
  811. private:
  812. const NUdf::TRefCountedPtr<THashedSetHolder> Parent;
  813. TValuesDictHashSet::const_iterator Iterator;
  814. TValuesDictHashSet::const_iterator End;
  815. bool AtStart;
  816. };
  817. THashedSetHolder(TMemoryUsageInfo* memInfo, THashedSetFiller filler,
  818. const TKeyTypes& types, bool isTuple, bool eagerFill, TType* encodedType,
  819. const NUdf::IHash* hash, const NUdf::IEquate* equate, const THolderFactory& holderFactory)
  820. : TComputationValue(memInfo)
  821. , Filler(filler)
  822. , Types(types)
  823. , Set(0, TValueHasher(Types, isTuple, hash), TValueEqual(Types, isTuple, equate))
  824. , IsBuilt(false)
  825. , HolderFactory(holderFactory)
  826. {
  827. if (encodedType) {
  828. Packer.emplace(true, encodedType);
  829. }
  830. if (eagerFill)
  831. LazyBuildDict();
  832. }
  833. private:
  834. bool Contains(const NUdf::TUnboxedValuePod& key) const override {
  835. LazyBuildDict();
  836. NUdf::TUnboxedValue encodedKey;
  837. if (Packer) {
  838. encodedKey = MakeString(Packer->Pack(key));
  839. }
  840. return Set.find(NUdf::TUnboxedValuePod(Packer ? encodedKey : key)) != Set.cend();
  841. }
  842. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
  843. LazyBuildDict();
  844. NUdf::TUnboxedValue encodedKey;
  845. if (Packer) {
  846. encodedKey = MakeString(Packer->Pack(key));
  847. }
  848. const auto it = Set.find(NUdf::TUnboxedValuePod(Packer ? encodedKey : key));
  849. if (it == Set.cend())
  850. return NUdf::TUnboxedValuePod();
  851. return NUdf::TUnboxedValuePod::Void();
  852. }
  853. NUdf::TUnboxedValue GetKeysIterator() const override {
  854. LazyBuildDict();
  855. return NUdf::TUnboxedValuePod(new TIterator(this));
  856. }
  857. NUdf::TUnboxedValue GetDictIterator() const override {
  858. LazyBuildDict();
  859. return NUdf::TUnboxedValuePod(new TIterator(this));
  860. }
  861. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  862. LazyBuildDict();
  863. return NUdf::TUnboxedValuePod(new TIterator(this));
  864. }
  865. NUdf::TUnboxedValue GetListIterator() const override {
  866. LazyBuildDict();
  867. return NUdf::TUnboxedValuePod(new TIterator(this));
  868. }
  869. ui64 GetDictLength() const override {
  870. LazyBuildDict();
  871. return Set.size();
  872. }
  873. bool HasDictItems() const override {
  874. LazyBuildDict();
  875. return !Set.empty();
  876. }
  877. bool IsSortedDict() const override {
  878. return false;
  879. }
  880. private:
  881. void LazyBuildDict() const {
  882. if (IsBuilt)
  883. return;
  884. Filler(Set);
  885. Filler = THashedSetFiller();
  886. IsBuilt = true;
  887. }
  888. private:
  889. mutable THashedSetFiller Filler;
  890. const TKeyTypes Types;
  891. mutable TValuesDictHashSet Set;
  892. mutable bool IsBuilt;
  893. const THolderFactory& HolderFactory;
  894. mutable std::optional<TValuePacker> Packer;
  895. };
  896. template <typename T, bool OptionalKey>
  897. class THashedSingleFixedSetHolder : public TComputationValue<THashedSingleFixedSetHolder<T, OptionalKey>> {
  898. public:
  899. using TSetType = TValuesDictHashSingleFixedSet<T>;
  900. class TIterator : public TComputationValue<TIterator> {
  901. public:
  902. enum class EState {
  903. AtStart,
  904. AtNull,
  905. Iterator
  906. };
  907. TIterator(const THashedSingleFixedSetHolder* parent)
  908. : TComputationValue<TIterator>(parent->GetMemInfo())
  909. , Parent(const_cast<THashedSingleFixedSetHolder*>(parent))
  910. , Iterator(Parent->Set.begin())
  911. , End(Parent->Set.end())
  912. , State(EState::AtStart)
  913. {
  914. }
  915. private:
  916. bool Skip() final {
  917. switch (State) {
  918. case EState::AtStart:
  919. State = OptionalKey && Parent->HasNull ? EState::AtNull : EState::Iterator;
  920. break;
  921. case EState::AtNull:
  922. State = EState::Iterator;
  923. break;
  924. case EState::Iterator:
  925. if (Iterator == End)
  926. return false;
  927. ++Iterator;
  928. break;
  929. }
  930. return EState::AtNull == State || Iterator != End;
  931. }
  932. bool Next(NUdf::TUnboxedValue& key) final {
  933. if (!Skip())
  934. return false;
  935. key = EState::AtNull == State ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(*Iterator);
  936. return true;
  937. }
  938. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
  939. if (!Next(key))
  940. return false;
  941. payload = NUdf::TUnboxedValuePod::Void();
  942. return true;
  943. }
  944. const NUdf::TRefCountedPtr<THashedSingleFixedSetHolder> Parent;
  945. typename TSetType::const_iterator Iterator;
  946. typename TSetType::const_iterator End;
  947. EState State;
  948. };
  949. THashedSingleFixedSetHolder(TMemoryUsageInfo* memInfo, TSetType&& set, bool hasNull)
  950. : TComputationValue<THashedSingleFixedSetHolder>(memInfo)
  951. , Set(std::move(set))
  952. , HasNull(hasNull)
  953. {
  954. MKQL_ENSURE(OptionalKey || !HasNull, "Null value is not allowed for non-optional key type");
  955. }
  956. private:
  957. bool Contains(const NUdf::TUnboxedValuePod& key) const final {
  958. if constexpr (OptionalKey) {
  959. if (!key) {
  960. return HasNull;
  961. }
  962. }
  963. return Set.find(key.Get<T>()) != Set.cend();
  964. }
  965. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
  966. if (Contains(key))
  967. return NUdf::TUnboxedValuePod::Void();
  968. return NUdf::TUnboxedValuePod();
  969. }
  970. NUdf::TUnboxedValue GetKeysIterator() const final {
  971. return NUdf::TUnboxedValuePod(new TIterator(this));
  972. }
  973. NUdf::TUnboxedValue GetDictIterator() const final {
  974. return NUdf::TUnboxedValuePod(new TIterator(this));
  975. }
  976. NUdf::TUnboxedValue GetPayloadsIterator() const final {
  977. return NUdf::TUnboxedValuePod(new TIterator(this));
  978. }
  979. NUdf::TUnboxedValue GetListIterator() const final {
  980. return NUdf::TUnboxedValuePod(new TIterator(this));
  981. }
  982. ui64 GetDictLength() const final {
  983. return Set.size() + ui64(OptionalKey && HasNull);
  984. }
  985. bool HasDictItems() const final {
  986. return !Set.empty() || (OptionalKey && HasNull);
  987. }
  988. bool IsSortedDict() const final {
  989. return false;
  990. }
  991. const TSetType Set;
  992. const bool HasNull;
  993. };
  994. template <typename T, bool OptionalKey>
  995. class THashedSingleFixedCompactSetHolder : public TComputationValue<THashedSingleFixedCompactSetHolder<T, OptionalKey>> {
  996. public:
  997. using TSetType = TValuesDictHashSingleFixedCompactSet<T>;
  998. class TIterator : public TComputationValue<TIterator> {
  999. public:
  1000. enum class EState {
  1001. AtStart,
  1002. AtNull,
  1003. Iterator
  1004. };
  1005. TIterator(const THashedSingleFixedCompactSetHolder* parent)
  1006. : TComputationValue<TIterator>(parent->GetMemInfo())
  1007. , Parent(const_cast<THashedSingleFixedCompactSetHolder*>(parent))
  1008. , Iterator(Parent->Set.Iterate())
  1009. , State(EState::AtStart)
  1010. {
  1011. }
  1012. private:
  1013. bool Skip() final {
  1014. switch (State) {
  1015. case EState::AtStart:
  1016. State = OptionalKey && Parent->HasNull ? EState::AtNull : EState::Iterator;
  1017. break;
  1018. case EState::AtNull:
  1019. State = EState::Iterator;
  1020. break;
  1021. case EState::Iterator:
  1022. if (!Iterator.Ok())
  1023. return false;
  1024. ++Iterator;
  1025. break;
  1026. }
  1027. return EState::AtNull == State || Iterator.Ok();
  1028. }
  1029. bool Next(NUdf::TUnboxedValue& key) final {
  1030. if (!Skip())
  1031. return false;
  1032. key = EState::AtNull == State ? NUdf::TUnboxedValuePod() : NUdf::TUnboxedValuePod(*Iterator);
  1033. return true;
  1034. }
  1035. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
  1036. if (!Next(key))
  1037. return false;
  1038. payload = NUdf::TUnboxedValuePod::Void();
  1039. return true;
  1040. }
  1041. const NUdf::TRefCountedPtr<THashedSingleFixedCompactSetHolder> Parent;
  1042. typename TSetType::TIterator Iterator;
  1043. EState State;
  1044. };
  1045. THashedSingleFixedCompactSetHolder(TMemoryUsageInfo* memInfo, TSetType&& set, bool hasNull)
  1046. : TComputationValue<THashedSingleFixedCompactSetHolder>(memInfo)
  1047. , Set(std::move(set))
  1048. , HasNull(hasNull)
  1049. {
  1050. MKQL_ENSURE(OptionalKey || !HasNull, "Null value is not allowed for non-optional key type");
  1051. }
  1052. private:
  1053. bool Contains(const NUdf::TUnboxedValuePod& key) const final {
  1054. if constexpr (OptionalKey) {
  1055. if (!key) {
  1056. return HasNull;
  1057. }
  1058. }
  1059. return Set.Has(key.Get<T>());
  1060. }
  1061. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
  1062. if (Contains(key))
  1063. return NUdf::TUnboxedValuePod::Void();
  1064. return NUdf::TUnboxedValuePod();
  1065. }
  1066. NUdf::TUnboxedValue GetKeysIterator() const final {
  1067. return NUdf::TUnboxedValuePod(new TIterator(this));
  1068. }
  1069. NUdf::TUnboxedValue GetDictIterator() const final {
  1070. return NUdf::TUnboxedValuePod(new TIterator(this));
  1071. }
  1072. NUdf::TUnboxedValue GetPayloadsIterator() const final {
  1073. return NUdf::TUnboxedValuePod(new TIterator(this));
  1074. }
  1075. NUdf::TUnboxedValue GetListIterator() const final {
  1076. return NUdf::TUnboxedValuePod(new TIterator(this));
  1077. }
  1078. ui64 GetDictLength() const final {
  1079. return Set.Size() + ui64(OptionalKey && HasNull);
  1080. }
  1081. bool HasDictItems() const final {
  1082. return !Set.Empty() || (OptionalKey && HasNull);
  1083. }
  1084. bool IsSortedDict() const final {
  1085. return false;
  1086. }
  1087. const TSetType Set;
  1088. const bool HasNull;
  1089. };
  1090. class THashedCompactSetHolder : public TComputationValue<THashedCompactSetHolder> {
  1091. public:
  1092. using TSetType = TValuesDictHashCompactSet;
  1093. class TIterator : public TComputationValue<TIterator> {
  1094. public:
  1095. TIterator(const THashedCompactSetHolder* parent)
  1096. : TComputationValue(parent->GetMemInfo())
  1097. , Parent(const_cast<THashedCompactSetHolder*>(parent))
  1098. , Iterator(Parent->Set.Iterate())
  1099. , AtStart(true)
  1100. {
  1101. }
  1102. private:
  1103. bool Skip() override {
  1104. if (AtStart) {
  1105. AtStart = false;
  1106. }
  1107. else {
  1108. if (!Iterator.Ok())
  1109. return false;
  1110. ++Iterator;
  1111. }
  1112. return Iterator.Ok();
  1113. }
  1114. bool Next(NUdf::TUnboxedValue& key) override {
  1115. if (!Skip())
  1116. return false;
  1117. key = Parent->KeyPacker.Unpack(GetSmallValue(*Iterator), Parent->Ctx->HolderFactory);
  1118. return true;
  1119. }
  1120. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
  1121. if (!Next(key))
  1122. return false;
  1123. payload = NUdf::TUnboxedValuePod::Void();
  1124. return true;
  1125. }
  1126. const NUdf::TRefCountedPtr<THashedCompactSetHolder> Parent;
  1127. typename TSetType::TIterator Iterator;
  1128. bool AtStart;
  1129. };
  1130. THashedCompactSetHolder(TMemoryUsageInfo* memInfo, TSetType&& set, TPagedArena&& pool, TType* keyType, TComputationContext* ctx)
  1131. : TComputationValue(memInfo)
  1132. , Pool(std::move(pool))
  1133. , Set(std::move(set))
  1134. , KeyPacker(true, keyType)
  1135. , Ctx(ctx)
  1136. {
  1137. }
  1138. private:
  1139. bool Contains(const NUdf::TUnboxedValuePod& key) const override {
  1140. auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
  1141. ui64 smallValue = AsSmallValue(serializedKey);
  1142. return Set.Has(smallValue);
  1143. }
  1144. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
  1145. auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
  1146. ui64 smallValue = AsSmallValue(serializedKey);
  1147. if (Set.Has(smallValue))
  1148. return NUdf::TUnboxedValuePod::Void();
  1149. return NUdf::TUnboxedValuePod();
  1150. }
  1151. NUdf::TUnboxedValue GetKeysIterator() const override {
  1152. return NUdf::TUnboxedValuePod(new TIterator(this));
  1153. }
  1154. NUdf::TUnboxedValue GetDictIterator() const override {
  1155. return NUdf::TUnboxedValuePod(new TIterator(this));
  1156. }
  1157. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  1158. return NUdf::TUnboxedValuePod(new TIterator(this));
  1159. }
  1160. NUdf::TUnboxedValue GetListIterator() const override {
  1161. return NUdf::TUnboxedValuePod(new TIterator(this));
  1162. }
  1163. ui64 GetDictLength() const override {
  1164. return Set.Size();
  1165. }
  1166. bool HasDictItems() const override {
  1167. return !Set.Empty();
  1168. }
  1169. bool IsSortedDict() const override {
  1170. return false;
  1171. }
  1172. private:
  1173. TPagedArena Pool;
  1174. const TSetType Set;
  1175. mutable TValuePacker KeyPacker;
  1176. TComputationContext* Ctx;
  1177. };
  1178. class THashedCompactMapHolder : public TComputationValue<THashedCompactMapHolder> {
  1179. public:
  1180. using TMapType = TValuesDictHashCompactMap;
  1181. template <bool NoSwap>
  1182. class TIterator : public TComputationValue<TIterator<NoSwap>> {
  1183. public:
  1184. TIterator(const THashedCompactMapHolder* parent)
  1185. : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
  1186. , Parent(const_cast<THashedCompactMapHolder*>(parent))
  1187. , Iterator(Parent->Map.Iterate())
  1188. , AtStart(true)
  1189. {
  1190. }
  1191. private:
  1192. bool Skip() override {
  1193. if (AtStart) {
  1194. AtStart = false;
  1195. }
  1196. else {
  1197. if (!Iterator.Ok())
  1198. return false;
  1199. ++Iterator;
  1200. }
  1201. return Iterator.Ok();
  1202. }
  1203. bool Next(NUdf::TUnboxedValue& key) override {
  1204. if (!Skip())
  1205. return false;
  1206. key = NoSwap ?
  1207. Parent->KeyPacker.Unpack(GetSmallValue(Iterator.Get().first), Parent->Ctx->HolderFactory):
  1208. Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.Get().second), Parent->Ctx->HolderFactory);
  1209. return true;
  1210. }
  1211. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
  1212. if (!Next(key))
  1213. return false;
  1214. payload = NoSwap ?
  1215. Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.Get().second), Parent->Ctx->HolderFactory):
  1216. Parent->KeyPacker.Unpack(GetSmallValue(Iterator.Get().first), Parent->Ctx->HolderFactory);
  1217. return true;
  1218. }
  1219. const NUdf::TRefCountedPtr<THashedCompactMapHolder> Parent;
  1220. typename TMapType::TIterator Iterator;
  1221. bool AtStart;
  1222. };
  1223. THashedCompactMapHolder(TMemoryUsageInfo* memInfo, TMapType&& map, TPagedArena&& pool,
  1224. TType* keyType, TType* payloadType, TComputationContext* ctx)
  1225. : TComputationValue(memInfo)
  1226. , Pool(std::move(pool))
  1227. , Map(std::move(map))
  1228. , KeyPacker(true, keyType)
  1229. , PayloadPacker(false, payloadType)
  1230. , Ctx(ctx)
  1231. {
  1232. }
  1233. private:
  1234. bool Contains(const NUdf::TUnboxedValuePod& key) const override {
  1235. auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
  1236. ui64 smallValue = AsSmallValue(serializedKey);
  1237. return Map.Has(smallValue);
  1238. }
  1239. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
  1240. auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
  1241. ui64 smallValue = AsSmallValue(serializedKey);
  1242. auto it = Map.Find(smallValue);
  1243. if (!it.Ok())
  1244. return NUdf::TUnboxedValuePod();
  1245. return PayloadPacker.Unpack(GetSmallValue(it.Get().second), Ctx->HolderFactory).Release().MakeOptional();
  1246. }
  1247. NUdf::TUnboxedValue GetKeysIterator() const override {
  1248. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1249. }
  1250. NUdf::TUnboxedValue GetDictIterator() const override {
  1251. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1252. }
  1253. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  1254. return NUdf::TUnboxedValuePod(new TIterator<false>(this));
  1255. }
  1256. ui64 GetDictLength() const override {
  1257. return Map.Size();
  1258. }
  1259. bool HasDictItems() const override {
  1260. return !Map.Empty();
  1261. }
  1262. bool IsSortedDict() const override {
  1263. return false;
  1264. }
  1265. TPagedArena Pool;
  1266. const TMapType Map;
  1267. mutable TValuePacker KeyPacker;
  1268. mutable TValuePacker PayloadPacker;
  1269. TComputationContext* Ctx;
  1270. };
  1271. class THashedCompactMultiMapHolder : public TComputationValue<THashedCompactMultiMapHolder> {
  1272. public:
  1273. using TMapType = TValuesDictHashCompactMultiMap;
  1274. using TMapIterator = typename TMapType::TIterator;
  1275. class TPayloadList: public TCustomListValue {
  1276. public:
  1277. class TIterator : public TComputationValue<TIterator> {
  1278. public:
  1279. TIterator(const THashedCompactMultiMapHolder* parent, TMapIterator from)
  1280. : TComputationValue(parent->GetMemInfo())
  1281. , Parent(const_cast<THashedCompactMultiMapHolder*>(parent))
  1282. , Iterator(from)
  1283. {
  1284. }
  1285. private:
  1286. bool Next(NUdf::TUnboxedValue& value) override {
  1287. if (!Iterator.Ok()) {
  1288. return false;
  1289. }
  1290. value = Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.GetValue()), Parent->CompCtx.HolderFactory);
  1291. ++Iterator;
  1292. return true;
  1293. }
  1294. bool Skip() override {
  1295. if (!Iterator.Ok()) {
  1296. return false;
  1297. }
  1298. ++Iterator;
  1299. return true;
  1300. }
  1301. const NUdf::TRefCountedPtr<THashedCompactMultiMapHolder> Parent;
  1302. TMapIterator Iterator;
  1303. };
  1304. TPayloadList(TMemoryUsageInfo* memInfo, const THashedCompactMultiMapHolder* parent, TMapIterator from)
  1305. : TCustomListValue(memInfo)
  1306. , Parent(const_cast<THashedCompactMultiMapHolder*>(parent))
  1307. , From(from)
  1308. {
  1309. Y_ASSERT(From.Ok());
  1310. }
  1311. private:
  1312. bool HasFastListLength() const override {
  1313. return true;
  1314. }
  1315. ui64 GetListLength() const override {
  1316. if (!Length) {
  1317. Length = Parent->Map.Count(From.GetKey());
  1318. }
  1319. return *Length;
  1320. }
  1321. bool HasListItems() const override {
  1322. return true;
  1323. }
  1324. NUdf::TUnboxedValue GetListIterator() const override {
  1325. return NUdf::TUnboxedValuePod(new TIterator(Parent.Get(), From));
  1326. }
  1327. const NUdf::TRefCountedPtr<THashedCompactMultiMapHolder> Parent;
  1328. TMapIterator From;
  1329. };
  1330. template <bool NoSwap>
  1331. class TIterator : public TComputationValue<TIterator<NoSwap>> {
  1332. public:
  1333. TIterator(const THashedCompactMultiMapHolder* parent)
  1334. : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
  1335. , Parent(const_cast<THashedCompactMultiMapHolder*>(parent))
  1336. , Iterator(parent->Map.Iterate())
  1337. {
  1338. }
  1339. private:
  1340. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
  1341. if (!Iterator.Ok()) {
  1342. return false;
  1343. }
  1344. if (NoSwap) {
  1345. key = Parent->KeyPacker.Unpack(GetSmallValue(Iterator.GetKey()), Parent->CompCtx.HolderFactory);
  1346. payload = Parent->CompCtx.HolderFactory.Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
  1347. } else {
  1348. payload = Parent->KeyPacker.Unpack(GetSmallValue(Iterator.GetKey()), Parent->CompCtx.HolderFactory);
  1349. key = Parent->CompCtx.HolderFactory.Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
  1350. }
  1351. Iterator.NextKey();
  1352. return true;
  1353. }
  1354. bool Next(NUdf::TUnboxedValue& key) override {
  1355. if (!Iterator.Ok()) {
  1356. return false;
  1357. }
  1358. key = NoSwap ?
  1359. Parent->KeyPacker.Unpack(GetSmallValue(Iterator.GetKey()), Parent->CompCtx.HolderFactory):
  1360. NUdf::TUnboxedValue(Parent->CompCtx.HolderFactory.Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter()));
  1361. Iterator.NextKey();
  1362. return true;
  1363. }
  1364. bool Skip() override {
  1365. if (!Iterator.Ok()) {
  1366. return false;
  1367. }
  1368. Iterator.NextKey();
  1369. return true;
  1370. }
  1371. const NUdf::TRefCountedPtr<THashedCompactMultiMapHolder> Parent;
  1372. TMapIterator Iterator;
  1373. };
  1374. THashedCompactMultiMapHolder(TMemoryUsageInfo* memInfo, TMapType&& map, TPagedArena&& pool,
  1375. TType* keyType, TType* payloadType, TComputationContext* ctx)
  1376. : TComputationValue(memInfo)
  1377. , Pool(std::move(pool))
  1378. , Map(std::move(map))
  1379. , KeyPacker(true, keyType)
  1380. , PayloadPacker(false, payloadType)
  1381. , CompCtx(*ctx)
  1382. {
  1383. }
  1384. private:
  1385. bool Contains(const NUdf::TUnboxedValuePod& key) const override {
  1386. auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
  1387. ui64 smallValue = AsSmallValue(serializedKey);
  1388. return Map.Has(smallValue);
  1389. }
  1390. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
  1391. auto serializedKey = KeyPacker.Pack(NUdf::TUnboxedValuePod(key));
  1392. ui64 smallValue = AsSmallValue(serializedKey);
  1393. auto it = Map.Find(smallValue);
  1394. if (!it.Ok())
  1395. return NUdf::TUnboxedValuePod();
  1396. return CompCtx.HolderFactory.Create<TPayloadList>(this, it);
  1397. }
  1398. NUdf::TUnboxedValue GetKeysIterator() const override {
  1399. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1400. }
  1401. NUdf::TUnboxedValue GetDictIterator() const override {
  1402. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1403. }
  1404. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  1405. return NUdf::TUnboxedValuePod(new TIterator<false>(this));
  1406. }
  1407. ui64 GetDictLength() const override {
  1408. return Map.UniqSize();
  1409. }
  1410. bool HasDictItems() const override {
  1411. return !Map.Empty();
  1412. }
  1413. bool IsSortedDict() const override {
  1414. return false;
  1415. }
  1416. TPagedArena Pool;
  1417. const TMapType Map;
  1418. mutable TValuePacker KeyPacker;
  1419. mutable TValuePacker PayloadPacker;
  1420. TComputationContext& CompCtx;
  1421. };
  1422. class THashedDictHolder: public TComputationValue<THashedDictHolder> {
  1423. public:
  1424. template <bool NoSwap>
  1425. class TIterator: public TTemporaryComputationValue<TIterator<NoSwap>> {
  1426. public:
  1427. TIterator(const THashedDictHolder* parent)
  1428. : TTemporaryComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
  1429. , Parent(const_cast<THashedDictHolder*>(parent))
  1430. , Iterator(Parent->Map.begin())
  1431. , End(Parent->Map.end())
  1432. , AtStart(true)
  1433. {
  1434. }
  1435. private:
  1436. bool Skip() override {
  1437. if (AtStart) {
  1438. AtStart = false;
  1439. } else {
  1440. if (Iterator == End)
  1441. return false;
  1442. ++Iterator;
  1443. }
  1444. return Iterator != End;
  1445. }
  1446. bool Next(NUdf::TUnboxedValue& key) override {
  1447. if (!Skip())
  1448. return false;
  1449. if (NoSwap) {
  1450. key = Iterator->first;
  1451. if (Parent->Packer) {
  1452. key = Parent->Packer->Unpack(key.AsStringRef(), Parent->HolderFactory);
  1453. }
  1454. } else {
  1455. key = Iterator->second;
  1456. }
  1457. return true;
  1458. }
  1459. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
  1460. if (!Next(key))
  1461. return false;
  1462. if (NoSwap) {
  1463. payload = Iterator->second;
  1464. } else {
  1465. payload = Iterator->first;
  1466. if (Parent->Packer) {
  1467. payload = Parent->Packer->Unpack(payload.AsStringRef(), Parent->HolderFactory);
  1468. }
  1469. }
  1470. return true;
  1471. }
  1472. const NUdf::TRefCountedPtr<THashedDictHolder> Parent;
  1473. TValuesDictHashMap::const_iterator Iterator;
  1474. TValuesDictHashMap::const_iterator End;
  1475. bool AtStart;
  1476. };
  1477. THashedDictHolder(TMemoryUsageInfo* memInfo, THashedDictFiller filler,
  1478. const TKeyTypes& types, bool isTuple, bool eagerFill, TType* encodedType,
  1479. const NUdf::IHash* hash, const NUdf::IEquate* equate, const THolderFactory& holderFactory)
  1480. : TComputationValue(memInfo)
  1481. , Filler(filler)
  1482. , Types(types)
  1483. , Map(0, TValueHasher(Types, isTuple, hash), TValueEqual(Types, isTuple, equate))
  1484. , IsBuilt(false)
  1485. , HolderFactory(holderFactory)
  1486. {
  1487. if (encodedType) {
  1488. Packer.emplace(true, encodedType);
  1489. }
  1490. if (eagerFill)
  1491. LazyBuildDict();
  1492. }
  1493. private:
  1494. bool Contains(const NUdf::TUnboxedValuePod& key) const override {
  1495. LazyBuildDict();
  1496. NUdf::TUnboxedValue encodedKey;
  1497. if (Packer) {
  1498. encodedKey = MakeString(Packer->Pack(key));
  1499. }
  1500. return Map.find(NUdf::TUnboxedValuePod(Packer ? encodedKey : key)) != Map.cend();
  1501. }
  1502. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
  1503. LazyBuildDict();
  1504. NUdf::TUnboxedValue encodedKey;
  1505. if (Packer) {
  1506. encodedKey = MakeString(Packer->Pack(key));
  1507. }
  1508. const auto it = Map.find(NUdf::TUnboxedValuePod(Packer ? encodedKey : key));
  1509. if (it == Map.cend())
  1510. return NUdf::TUnboxedValuePod();
  1511. return it->second.MakeOptional();
  1512. }
  1513. NUdf::TUnboxedValue GetKeysIterator() const override {
  1514. LazyBuildDict();
  1515. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1516. }
  1517. NUdf::TUnboxedValue GetDictIterator() const override {
  1518. LazyBuildDict();
  1519. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1520. }
  1521. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  1522. LazyBuildDict();
  1523. return NUdf::TUnboxedValuePod(new TIterator<false>(this));
  1524. }
  1525. ui64 GetDictLength() const override {
  1526. LazyBuildDict();
  1527. return Map.size();
  1528. }
  1529. bool HasDictItems() const override {
  1530. LazyBuildDict();
  1531. return !Map.empty();
  1532. }
  1533. bool IsSortedDict() const override {
  1534. return false;
  1535. }
  1536. private:
  1537. void LazyBuildDict() const {
  1538. if (IsBuilt)
  1539. return;
  1540. Filler(Map);
  1541. Filler = THashedDictFiller();
  1542. IsBuilt = true;
  1543. }
  1544. private:
  1545. mutable THashedDictFiller Filler;
  1546. const TKeyTypes Types;
  1547. mutable TValuesDictHashMap Map;
  1548. mutable bool IsBuilt;
  1549. const THolderFactory& HolderFactory;
  1550. std::optional<TValuePacker> Packer;
  1551. };
  1552. template <typename T, bool OptionalKey>
  1553. class THashedSingleFixedMapHolder : public TComputationValue<THashedSingleFixedMapHolder<T, OptionalKey>> {
  1554. public:
  1555. using TMapType = TValuesDictHashSingleFixedMap<T>;
  1556. template <bool NoSwap>
  1557. class TIterator : public TComputationValue<TIterator<NoSwap>> {
  1558. public:
  1559. enum class EState {
  1560. AtStart,
  1561. AtNull,
  1562. Iterator
  1563. };
  1564. TIterator(const THashedSingleFixedMapHolder* parent)
  1565. : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
  1566. , Parent(const_cast<THashedSingleFixedMapHolder*>(parent))
  1567. , Iterator(Parent->Map.begin())
  1568. , End(Parent->Map.end())
  1569. , State(EState::AtStart)
  1570. {
  1571. }
  1572. private:
  1573. bool Skip() final {
  1574. switch (State) {
  1575. case EState::AtStart:
  1576. State = OptionalKey && Parent->NullPayload.has_value() ? EState::AtNull : EState::Iterator;
  1577. break;
  1578. case EState::AtNull:
  1579. State = EState::Iterator;
  1580. break;
  1581. case EState::Iterator:
  1582. if (Iterator == End) {
  1583. return false;
  1584. }
  1585. ++Iterator;
  1586. break;
  1587. }
  1588. return EState::AtNull == State || Iterator != End;
  1589. }
  1590. bool Next(NUdf::TUnboxedValue& key) final {
  1591. if (!Skip())
  1592. return false;
  1593. key = NoSwap
  1594. ? (EState::AtNull == State ? NUdf::TUnboxedValue() : NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator->first)))
  1595. : (EState::AtNull == State ? *Parent->NullPayload : Iterator->second);
  1596. return true;
  1597. }
  1598. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
  1599. if (!Next(key))
  1600. return false;
  1601. payload = NoSwap
  1602. ? (EState::AtNull == State ? *Parent->NullPayload : Iterator->second)
  1603. : (EState::AtNull == State ? NUdf::TUnboxedValue() : NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator->first)));
  1604. return true;
  1605. }
  1606. const NUdf::TRefCountedPtr<THashedSingleFixedMapHolder> Parent;
  1607. typename TMapType::const_iterator Iterator;
  1608. typename TMapType::const_iterator End;
  1609. EState State;
  1610. };
  1611. THashedSingleFixedMapHolder(TMemoryUsageInfo* memInfo, TValuesDictHashSingleFixedMap<T>&& map, std::optional<NUdf::TUnboxedValue>&& nullPayload)
  1612. : TComputationValue<THashedSingleFixedMapHolder>(memInfo)
  1613. , Map(std::move(map))
  1614. , NullPayload(std::move(nullPayload))
  1615. {
  1616. }
  1617. private:
  1618. bool Contains(const NUdf::TUnboxedValuePod& key) const final {
  1619. if constexpr (OptionalKey) {
  1620. if (!key) {
  1621. return NullPayload.has_value();
  1622. }
  1623. }
  1624. return Map.find(key.Get<T>()) != Map.end();
  1625. }
  1626. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
  1627. if constexpr (OptionalKey) {
  1628. if (!key) {
  1629. return NullPayload.has_value() ? NullPayload->MakeOptional() : NUdf::TUnboxedValuePod();
  1630. }
  1631. }
  1632. const auto it = Map.find(key.Get<T>());
  1633. if (it == Map.end())
  1634. return NUdf::TUnboxedValuePod();
  1635. return it->second.MakeOptional();
  1636. }
  1637. NUdf::TUnboxedValue GetKeysIterator() const final {
  1638. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1639. }
  1640. NUdf::TUnboxedValue GetDictIterator() const final {
  1641. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1642. }
  1643. NUdf::TUnboxedValue GetPayloadsIterator() const final {
  1644. return NUdf::TUnboxedValuePod(new TIterator<false>(this));
  1645. }
  1646. ui64 GetDictLength() const final {
  1647. return Map.size() + ui64(OptionalKey && NullPayload.has_value());
  1648. }
  1649. bool HasDictItems() const final {
  1650. return !Map.empty() || (OptionalKey && NullPayload.has_value());
  1651. }
  1652. bool IsSortedDict() const final {
  1653. return false;
  1654. }
  1655. const TMapType Map;
  1656. const std::optional<NUdf::TUnboxedValue> NullPayload;
  1657. };
  1658. template <typename T, bool OptionalKey>
  1659. class THashedSingleFixedCompactMapHolder : public TComputationValue<THashedSingleFixedCompactMapHolder<T, OptionalKey>> {
  1660. public:
  1661. using TMapType = TValuesDictHashSingleFixedCompactMap<T>;
  1662. template <bool NoSwap>
  1663. class TIterator : public TComputationValue<TIterator<NoSwap>> {
  1664. public:
  1665. enum class EState {
  1666. AtStart,
  1667. AtNull,
  1668. Iterator
  1669. };
  1670. TIterator(const THashedSingleFixedCompactMapHolder* parent)
  1671. : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
  1672. , Parent(const_cast<THashedSingleFixedCompactMapHolder*>(parent))
  1673. , Iterator(Parent->Map.Iterate())
  1674. , State(EState::AtStart)
  1675. {
  1676. }
  1677. private:
  1678. bool Skip() final {
  1679. switch (State) {
  1680. case EState::AtStart:
  1681. State = OptionalKey && Parent->NullPayload.has_value() ? EState::AtNull : EState::Iterator;
  1682. break;
  1683. case EState::AtNull:
  1684. State = EState::Iterator;
  1685. break;
  1686. case EState::Iterator:
  1687. if (Iterator.Ok())
  1688. ++Iterator;
  1689. break;
  1690. }
  1691. return EState::AtNull == State || Iterator.Ok();
  1692. }
  1693. bool Next(NUdf::TUnboxedValue& key) final {
  1694. if (!Skip())
  1695. return false;
  1696. key = NoSwap
  1697. ? (EState::AtNull == State
  1698. ? NUdf::TUnboxedValue()
  1699. : NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator.Get().first))
  1700. )
  1701. : (EState::AtNull == State
  1702. ? Parent->PayloadPacker.Unpack(GetSmallValue(*Parent->NullPayload), Parent->Ctx->HolderFactory)
  1703. : Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.Get().second), Parent->Ctx->HolderFactory)
  1704. );
  1705. return true;
  1706. }
  1707. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) final {
  1708. if (!Next(key))
  1709. return false;
  1710. payload = NoSwap
  1711. ? (EState::AtNull == State
  1712. ? Parent->PayloadPacker.Unpack(GetSmallValue(*Parent->NullPayload), Parent->Ctx->HolderFactory)
  1713. : Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.Get().second), Parent->Ctx->HolderFactory)
  1714. )
  1715. : (EState::AtNull == State
  1716. ? NUdf::TUnboxedValue()
  1717. : NUdf::TUnboxedValue(NUdf::TUnboxedValuePod(Iterator.Get().first))
  1718. );
  1719. return true;
  1720. }
  1721. const NUdf::TRefCountedPtr<THashedSingleFixedCompactMapHolder> Parent;
  1722. typename TMapType::TIterator Iterator;
  1723. EState State;
  1724. };
  1725. THashedSingleFixedCompactMapHolder(TMemoryUsageInfo* memInfo, TMapType&& map, std::optional<ui64>&& nullPayload, TPagedArena&& pool,
  1726. TType* payloadType, TComputationContext* ctx)
  1727. : TComputationValue<THashedSingleFixedCompactMapHolder>(memInfo)
  1728. , Pool(std::move(pool))
  1729. , Map(std::move(map))
  1730. , NullPayload(std::move(nullPayload))
  1731. , PayloadPacker(false, payloadType)
  1732. , Ctx(ctx)
  1733. {
  1734. }
  1735. private:
  1736. bool Contains(const NUdf::TUnboxedValuePod& key) const final {
  1737. if constexpr (OptionalKey) {
  1738. if (!key) {
  1739. return NullPayload.has_value();
  1740. }
  1741. }
  1742. return Map.Has(key.Get<T>());
  1743. }
  1744. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
  1745. if constexpr (OptionalKey) {
  1746. if (!key) {
  1747. return NullPayload.has_value()
  1748. ? PayloadPacker.Unpack(GetSmallValue(*NullPayload), Ctx->HolderFactory).Release().MakeOptional()
  1749. : NUdf::TUnboxedValuePod();
  1750. }
  1751. }
  1752. auto it = Map.Find(key.Get<T>());
  1753. if (!it.Ok())
  1754. return NUdf::TUnboxedValuePod();
  1755. return PayloadPacker.Unpack(GetSmallValue(it.Get().second), Ctx->HolderFactory).Release().MakeOptional();
  1756. }
  1757. NUdf::TUnboxedValue GetKeysIterator() const final {
  1758. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1759. }
  1760. NUdf::TUnboxedValue GetDictIterator() const final {
  1761. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1762. }
  1763. NUdf::TUnboxedValue GetPayloadsIterator() const final {
  1764. return NUdf::TUnboxedValuePod(new TIterator<false>(this));
  1765. }
  1766. ui64 GetDictLength() const final {
  1767. return Map.Size() + ui64(OptionalKey && NullPayload.has_value());
  1768. }
  1769. bool HasDictItems() const final {
  1770. return !Map.Empty() || (OptionalKey && NullPayload.has_value());
  1771. }
  1772. bool IsSortedDict() const final {
  1773. return false;
  1774. }
  1775. private:
  1776. TPagedArena Pool;
  1777. const TMapType Map;
  1778. const std::optional<ui64> NullPayload;
  1779. mutable TValuePacker PayloadPacker;
  1780. TComputationContext* Ctx;
  1781. };
  1782. template <typename T, bool OptionalKey>
  1783. class THashedSingleFixedCompactMultiMapHolder : public TComputationValue<THashedSingleFixedCompactMultiMapHolder<T, OptionalKey>> {
  1784. public:
  1785. using TMapType = TValuesDictHashSingleFixedCompactMultiMap<T>;
  1786. using TMapIterator = typename TMapType::TIterator;
  1787. class TPayloadList: public TCustomListValue {
  1788. public:
  1789. class TIterator : public TComputationValue<TIterator> {
  1790. public:
  1791. TIterator(const THashedSingleFixedCompactMultiMapHolder* parent, TMapIterator from)
  1792. : TComputationValue<TIterator>(parent->GetMemInfo())
  1793. , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
  1794. , Iterator(from)
  1795. {
  1796. }
  1797. private:
  1798. bool Next(NUdf::TUnboxedValue& value) final {
  1799. if (!Iterator.Ok()) {
  1800. return false;
  1801. }
  1802. value = Parent->PayloadPacker.Unpack(GetSmallValue(Iterator.GetValue()), Parent->Ctx->HolderFactory);
  1803. ++Iterator;
  1804. return true;
  1805. }
  1806. bool Skip() final {
  1807. if (!Iterator.Ok()) {
  1808. return false;
  1809. }
  1810. ++Iterator;
  1811. return true;
  1812. }
  1813. const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
  1814. TMapIterator Iterator;
  1815. };
  1816. TPayloadList(TMemoryUsageInfo* memInfo, const THashedSingleFixedCompactMultiMapHolder* parent, TMapIterator from)
  1817. : TCustomListValue(memInfo)
  1818. , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
  1819. , From(from)
  1820. {
  1821. Y_ASSERT(From.Ok());
  1822. }
  1823. bool HasFastListLength() const final {
  1824. return true;
  1825. }
  1826. ui64 GetListLength() const final {
  1827. if (!Length) {
  1828. Length = Parent->Map.Count(From.GetKey());
  1829. }
  1830. return *Length;
  1831. }
  1832. bool HasListItems() const final {
  1833. return true;
  1834. }
  1835. NUdf::TUnboxedValue GetListIterator() const final {
  1836. return NUdf::TUnboxedValuePod(new TIterator(Parent.Get(), From));
  1837. }
  1838. const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
  1839. TMapIterator From;
  1840. };
  1841. class TNullPayloadList: public TCustomListValue {
  1842. public:
  1843. class TIterator : public TComputationValue<TIterator> {
  1844. public:
  1845. TIterator(const THashedSingleFixedCompactMultiMapHolder* parent)
  1846. : TComputationValue<TIterator>(parent->GetMemInfo())
  1847. , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
  1848. , Iterator(Parent->NullPayloads.cbegin())
  1849. {
  1850. }
  1851. private:
  1852. bool Next(NUdf::TUnboxedValue& value) final {
  1853. if (Iterator == Parent->NullPayloads.cend()) {
  1854. return false;
  1855. }
  1856. value = Parent->PayloadPacker.Unpack(GetSmallValue(*Iterator), Parent->Ctx->HolderFactory);
  1857. ++Iterator;
  1858. return true;
  1859. }
  1860. bool Skip() final {
  1861. if (Iterator == Parent->NullPayloads.cend()) {
  1862. return false;
  1863. }
  1864. ++Iterator;
  1865. return true;
  1866. }
  1867. const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
  1868. typename std::vector<ui64>::const_iterator Iterator;
  1869. };
  1870. TNullPayloadList(TMemoryUsageInfo* memInfo, const THashedSingleFixedCompactMultiMapHolder* parent)
  1871. : TCustomListValue(memInfo)
  1872. , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
  1873. {
  1874. }
  1875. bool HasFastListLength() const final {
  1876. return true;
  1877. }
  1878. ui64 GetListLength() const final {
  1879. if (!Length) {
  1880. Length = Parent->NullPayloads.size();
  1881. }
  1882. return *Length;
  1883. }
  1884. bool HasListItems() const final {
  1885. return true;
  1886. }
  1887. NUdf::TUnboxedValue GetListIterator() const final {
  1888. return NUdf::TUnboxedValuePod(new TIterator(Parent.Get()));
  1889. }
  1890. const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
  1891. };
  1892. template <bool NoSwap>
  1893. class TIterator : public TComputationValue<TIterator<NoSwap>> {
  1894. public:
  1895. TIterator(const THashedSingleFixedCompactMultiMapHolder* parent)
  1896. : TComputationValue<TIterator<NoSwap>>(parent->GetMemInfo())
  1897. , Parent(const_cast<THashedSingleFixedCompactMultiMapHolder*>(parent))
  1898. , Iterator(parent->Map.Iterate())
  1899. , AtNull(OptionalKey && !parent->NullPayloads.empty())
  1900. {
  1901. }
  1902. private:
  1903. bool Next(NUdf::TUnboxedValue& key) override {
  1904. if (AtNull) {
  1905. AtNull = false;
  1906. key = NoSwap
  1907. ? NUdf::TUnboxedValuePod()
  1908. : Parent->Ctx->HolderFactory.template Create<TNullPayloadList>(Parent.Get());
  1909. return true;
  1910. }
  1911. if (!Iterator.Ok()) {
  1912. return false;
  1913. }
  1914. key = NoSwap ?
  1915. NUdf::TUnboxedValuePod(Iterator.GetKey()):
  1916. Parent->Ctx->HolderFactory.template Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
  1917. Iterator.NextKey();
  1918. return true;
  1919. }
  1920. bool NextPair(NUdf::TUnboxedValue& key, NUdf::TUnboxedValue& payload) override {
  1921. if (AtNull) {
  1922. AtNull = false;
  1923. if (NoSwap) {
  1924. key = NUdf::TUnboxedValuePod();
  1925. payload = Parent->Ctx->HolderFactory.template Create<TNullPayloadList>(Parent.Get());
  1926. } else {
  1927. payload = NUdf::TUnboxedValuePod();
  1928. key = Parent->Ctx->HolderFactory.template Create<TNullPayloadList>(Parent.Get());
  1929. }
  1930. return true;
  1931. }
  1932. if (!Iterator.Ok()) {
  1933. return false;
  1934. }
  1935. if (NoSwap) {
  1936. key = NUdf::TUnboxedValuePod(Iterator.GetKey());
  1937. payload = Parent->Ctx->HolderFactory.template Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
  1938. } else {
  1939. payload = NUdf::TUnboxedValuePod(Iterator.GetKey());
  1940. key = Parent->Ctx->HolderFactory.template Create<TPayloadList>(Parent.Get(), Iterator.MakeCurrentKeyIter());
  1941. }
  1942. Iterator.NextKey();
  1943. return true;
  1944. }
  1945. bool Skip() override {
  1946. if (AtNull) {
  1947. AtNull = false;
  1948. return true;
  1949. }
  1950. if (!Iterator.Ok()) {
  1951. return false;
  1952. }
  1953. Iterator.NextKey();
  1954. return true;
  1955. }
  1956. const NUdf::TRefCountedPtr<THashedSingleFixedCompactMultiMapHolder> Parent;
  1957. TMapIterator Iterator;
  1958. bool AtNull;
  1959. };
  1960. THashedSingleFixedCompactMultiMapHolder(TMemoryUsageInfo* memInfo, TMapType&& map, std::vector<ui64>&& nullPayloads, TPagedArena&& pool,
  1961. TType* payloadType, TComputationContext* ctx)
  1962. : TComputationValue<THashedSingleFixedCompactMultiMapHolder>(memInfo)
  1963. , Pool(std::move(pool))
  1964. , Map(std::move(map))
  1965. , NullPayloads(std::move(nullPayloads))
  1966. , PayloadPacker(false, payloadType)
  1967. , Ctx(ctx)
  1968. {
  1969. }
  1970. private:
  1971. bool Contains(const NUdf::TUnboxedValuePod& key) const override {
  1972. if constexpr (OptionalKey) {
  1973. if (!key) {
  1974. return !NullPayloads.empty();
  1975. }
  1976. }
  1977. return Map.Has(key.Get<T>());
  1978. }
  1979. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const override {
  1980. if constexpr (OptionalKey) {
  1981. if (!key) {
  1982. return NullPayloads.empty()
  1983. ? NUdf::TUnboxedValuePod()
  1984. : Ctx->HolderFactory.Create<TNullPayloadList>(this);
  1985. }
  1986. }
  1987. const auto it = Map.Find(key.Get<T>());
  1988. if (!it.Ok())
  1989. return NUdf::TUnboxedValuePod();
  1990. return Ctx->HolderFactory.Create<TPayloadList>(this, it);
  1991. }
  1992. NUdf::TUnboxedValue GetKeysIterator() const override {
  1993. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1994. }
  1995. NUdf::TUnboxedValue GetDictIterator() const override {
  1996. return NUdf::TUnboxedValuePod(new TIterator<true>(this));
  1997. }
  1998. NUdf::TUnboxedValue GetPayloadsIterator() const override {
  1999. return NUdf::TUnboxedValuePod(new TIterator<false>(this));
  2000. }
  2001. ui64 GetDictLength() const override {
  2002. return Map.UniqSize() + ui64(OptionalKey && !NullPayloads.empty());
  2003. }
  2004. bool HasDictItems() const override {
  2005. return !Map.Empty() || (OptionalKey && !NullPayloads.empty());
  2006. }
  2007. bool IsSortedDict() const override {
  2008. return false;
  2009. }
  2010. private:
  2011. TPagedArena Pool;
  2012. const TMapType Map;
  2013. const std::vector<ui64> NullPayloads;
  2014. mutable TValuePacker PayloadPacker;
  2015. TComputationContext* Ctx;
  2016. };
  2017. class TVariantHolder : public TComputationValue<TVariantHolder> {
  2018. public:
  2019. TVariantHolder(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& item, ui32 index)
  2020. : TComputationValue(memInfo)
  2021. , Item(std::move(item))
  2022. , Index(index)
  2023. {
  2024. }
  2025. private:
  2026. NUdf::TUnboxedValue GetVariantItem() const override {
  2027. return Item;
  2028. }
  2029. ui32 GetVariantIndex() const override {
  2030. return Index;
  2031. }
  2032. const NUdf::TUnboxedValue Item;
  2033. const ui32 Index;
  2034. };
  2035. class TListIteratorHolder : public TComputationValue<TListIteratorHolder> {
  2036. public:
  2037. TListIteratorHolder(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& list)
  2038. : TComputationValue(memInfo)
  2039. , List(std::move(list))
  2040. , Iter(List.GetListIterator())
  2041. {}
  2042. private:
  2043. NUdf::EFetchStatus Fetch(NUdf::TUnboxedValue& result) override {
  2044. return Iter.Next(result) ? NUdf::EFetchStatus::Ok : NUdf::EFetchStatus::Finish;
  2045. }
  2046. const NUdf::TUnboxedValue List;
  2047. const NUdf::TUnboxedValue Iter;
  2048. };
  2049. class TLimitedList: public TComputationValue<TLimitedList> {
  2050. public:
  2051. class TIterator: public TComputationValue<TIterator> {
  2052. public:
  2053. TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& iter, TMaybe<ui64> skip, TMaybe<ui64> take)
  2054. : TComputationValue(memInfo)
  2055. , Iter(std::move(iter))
  2056. , Skip_(skip)
  2057. , Take_(take)
  2058. , Index(Max<ui64>())
  2059. {
  2060. }
  2061. private:
  2062. bool Next(NUdf::TUnboxedValue& value) override {
  2063. if (!Iter) {
  2064. return false;
  2065. }
  2066. if (Skip_) {
  2067. while ((Index + 1) < Skip_.GetRef()) {
  2068. if (!Iter.Skip()) {
  2069. Iter = NUdf::TUnboxedValue();
  2070. return false;
  2071. }
  2072. ++Index;
  2073. }
  2074. }
  2075. if (Take_ && ((Index + 1) - Skip_.GetOrElse(0)) >= Take_.GetRef()) {
  2076. Iter = NUdf::TUnboxedValue();
  2077. return false;
  2078. }
  2079. if (!Iter.Next(value)) {
  2080. Iter = NUdf::TUnboxedValue();
  2081. return false;
  2082. }
  2083. ++Index;
  2084. return true;
  2085. }
  2086. bool Skip() override {
  2087. if (!Iter) {
  2088. return false;
  2089. }
  2090. if (Skip_) {
  2091. while ((Index + 1) < Skip_.GetRef()) {
  2092. if (!Iter.Skip()) {
  2093. Iter = NUdf::TUnboxedValue();
  2094. return false;
  2095. }
  2096. ++Index;
  2097. }
  2098. }
  2099. if (Take_ && ((Index + 1) - Skip_.GetOrElse(0)) >= Take_.GetRef()) {
  2100. Iter = NUdf::TUnboxedValue();
  2101. return false;
  2102. }
  2103. if (!Iter.Skip()) {
  2104. Iter = NUdf::TUnboxedValue();
  2105. return false;
  2106. }
  2107. ++Index;
  2108. return true;
  2109. }
  2110. NUdf::TUnboxedValue Iter;
  2111. const TMaybe<ui64> Skip_;
  2112. const TMaybe<ui64> Take_;
  2113. ui64 Index;
  2114. };
  2115. TLimitedList(TMemoryUsageInfo* memInfo, NUdf::TRefCountedPtr<NUdf::IBoxedValue> parent, TMaybe<ui64> skip, TMaybe<ui64> take)
  2116. : TComputationValue(memInfo)
  2117. , Parent(parent)
  2118. , Skip(skip)
  2119. , Take(take)
  2120. {
  2121. }
  2122. private:
  2123. bool HasFastListLength() const override {
  2124. return Length.Defined();
  2125. }
  2126. ui64 GetListLength() const override {
  2127. if (!Length) {
  2128. ui64 length = NUdf::TBoxedValueAccessor::GetListLength(*Parent);
  2129. if (Skip) {
  2130. if (Skip.GetRef() >= length) {
  2131. length = 0;
  2132. } else {
  2133. length -= Skip.GetRef();
  2134. }
  2135. }
  2136. if (Take) {
  2137. length = Min(length, Take.GetRef());
  2138. }
  2139. Length = length;
  2140. }
  2141. return Length.GetRef();
  2142. }
  2143. ui64 GetEstimatedListLength() const override {
  2144. return GetListLength();
  2145. }
  2146. bool HasListItems() const override {
  2147. if (HasItems) {
  2148. return *HasItems;
  2149. }
  2150. if (Length) {
  2151. HasItems = (*Length != 0);
  2152. return *HasItems;
  2153. }
  2154. HasItems = GetListIterator().Skip();
  2155. return *HasItems;
  2156. }
  2157. NUdf::TUnboxedValue GetListIterator() const override {
  2158. return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), NUdf::TBoxedValueAccessor::GetListIterator(*Parent), Skip, Take));
  2159. }
  2160. NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
  2161. if (!count) {
  2162. return const_cast<TLimitedList*>(this);
  2163. }
  2164. if (Length) {
  2165. if (count >= Length.GetRef()) {
  2166. return builder.NewEmptyList().Release().AsBoxed();
  2167. }
  2168. }
  2169. ui64 prevSkip = Skip.GetOrElse(0);
  2170. if (count > Max<ui64>() - prevSkip) {
  2171. return builder.NewEmptyList().Release().AsBoxed();
  2172. }
  2173. const ui64 newSkip = prevSkip + count;
  2174. TMaybe<ui64> newTake = Take;
  2175. if (newTake) {
  2176. if (count >= newTake.GetRef()) {
  2177. return builder.NewEmptyList().Release().AsBoxed();
  2178. }
  2179. newTake = newTake.GetRef() - count;
  2180. }
  2181. return new TLimitedList(GetMemInfo(), Parent, newSkip, newTake);
  2182. }
  2183. NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const override {
  2184. if (!count) {
  2185. return builder.NewEmptyList().Release().AsBoxed();
  2186. }
  2187. if (Length) {
  2188. if (count >= Length.GetRef()) {
  2189. return const_cast<TLimitedList*>(this);
  2190. }
  2191. }
  2192. TMaybe<ui64> newTake = Take;
  2193. if (newTake) {
  2194. newTake = Min(count, newTake.GetRef());
  2195. } else {
  2196. newTake = count;
  2197. }
  2198. return new TLimitedList(GetMemInfo(), Parent, Skip, newTake);
  2199. }
  2200. NUdf::TRefCountedPtr<NUdf::IBoxedValue> Parent;
  2201. TMaybe<ui64> Skip;
  2202. TMaybe<ui64> Take;
  2203. mutable TMaybe<ui64> Length;
  2204. mutable TMaybe<bool> HasItems;
  2205. };
  2206. class TLazyListDecorator : public TComputationValue<TLazyListDecorator> {
  2207. public:
  2208. TLazyListDecorator(TMemoryUsageInfo* memInfo, NUdf::IBoxedValuePtr&& list)
  2209. : TComputationValue(memInfo), List(std::move(list))
  2210. {}
  2211. private:
  2212. bool HasListItems() const final {
  2213. return NUdf::TBoxedValueAccessor::HasListItems(*List);
  2214. }
  2215. bool HasDictItems() const final {
  2216. return NUdf::TBoxedValueAccessor::HasDictItems(*List);
  2217. }
  2218. bool HasFastListLength() const final {
  2219. return NUdf::TBoxedValueAccessor::HasFastListLength(*List);
  2220. }
  2221. ui64 GetListLength() const final {
  2222. return NUdf::TBoxedValueAccessor::GetListLength(*List);
  2223. }
  2224. ui64 GetDictLength() const final {
  2225. return NUdf::TBoxedValueAccessor::GetDictLength(*List);
  2226. }
  2227. ui64 GetEstimatedListLength() const final {
  2228. return NUdf::TBoxedValueAccessor::GetEstimatedListLength(*List);
  2229. }
  2230. NUdf::TUnboxedValue GetListIterator() const final {
  2231. return NUdf::TBoxedValueAccessor::GetListIterator(*List);
  2232. }
  2233. NUdf::TUnboxedValue GetDictIterator() const final {
  2234. return NUdf::TBoxedValueAccessor::GetDictIterator(*List);
  2235. }
  2236. NUdf::TUnboxedValue GetPayloadsIterator() const final {
  2237. return NUdf::TBoxedValueAccessor::GetPayloadsIterator(*List);
  2238. }
  2239. NUdf::TUnboxedValue GetKeysIterator() const final {
  2240. return NUdf::TBoxedValueAccessor::GetKeysIterator(*List);
  2241. }
  2242. NUdf::IBoxedValuePtr ReverseListImpl(const NUdf::IValueBuilder& builder) const final {
  2243. return NUdf::TBoxedValueAccessor::ReverseListImpl(*List, builder);
  2244. }
  2245. NUdf::IBoxedValuePtr SkipListImpl(const NUdf::IValueBuilder& builder, ui64 count) const final {
  2246. return NUdf::TBoxedValueAccessor::SkipListImpl(*List, builder, count);
  2247. }
  2248. NUdf::IBoxedValuePtr TakeListImpl(const NUdf::IValueBuilder& builder, ui64 count) const final {
  2249. return NUdf::TBoxedValueAccessor::TakeListImpl(*List, builder, count);
  2250. }
  2251. NUdf::IBoxedValuePtr ToIndexDictImpl(const NUdf::IValueBuilder& builder) const final {
  2252. return NUdf::TBoxedValueAccessor::ToIndexDictImpl(*List, builder);
  2253. }
  2254. bool Contains(const NUdf::TUnboxedValuePod& key) const final {
  2255. return NUdf::TBoxedValueAccessor::Contains(*List, key);
  2256. }
  2257. NUdf::TUnboxedValue Lookup(const NUdf::TUnboxedValuePod& key) const final {
  2258. return NUdf::TBoxedValueAccessor::Lookup(*List, key);
  2259. }
  2260. NUdf::TUnboxedValue GetElement(ui32 index) const final {
  2261. return NUdf::TBoxedValueAccessor::GetElement(*List, index);
  2262. }
  2263. const NUdf::TUnboxedValue* GetElements() const final {
  2264. return nullptr;
  2265. }
  2266. bool IsSortedDict() const final {
  2267. return NUdf::TBoxedValueAccessor::IsSortedDict(*List);
  2268. }
  2269. const NUdf::IBoxedValuePtr List;
  2270. };
  2271. } // namespace
  2272. ///////////////////////////////////////////////////////////////////////////////
  2273. // TDictValueBuilder
  2274. ///////////////////////////////////////////////////////////////////////////////
  2275. class TDictValueBuilder: public NUdf::IDictValueBuilder
  2276. {
  2277. public:
  2278. TDictValueBuilder(
  2279. const THolderFactory& holderFactory,
  2280. const TKeyTypes& types,
  2281. bool isTuple,
  2282. ui32 dictFlags,
  2283. TType* encodeType,
  2284. const NUdf::IHash* hash,
  2285. const NUdf::IEquate* equate,
  2286. const NUdf::ICompare* compare)
  2287. : HolderFactory_(holderFactory)
  2288. , Types_(types)
  2289. , IsTuple_(isTuple)
  2290. , DictFlags_(dictFlags)
  2291. , EncodeType_(encodeType)
  2292. , Hash_(hash)
  2293. , Equate_(equate)
  2294. , Compare_(compare)
  2295. {
  2296. Items_.reserve(10);
  2297. }
  2298. NUdf::IDictValueBuilder& Add(NUdf::TUnboxedValue&& key, NUdf::TUnboxedValue&& value) override
  2299. {
  2300. Items_.emplace_back(std::move(key), std::move(value));
  2301. return *this;
  2302. }
  2303. NUdf::TUnboxedValue Build() override {
  2304. if (Items_.empty())
  2305. return HolderFactory_.GetEmptyContainerLazy();
  2306. if (DictFlags_ & NUdf::TDictFlags::Hashed) {
  2307. auto prepareFn = (DictFlags_ & NUdf::TDictFlags::Multi)
  2308. ? &TDictValueBuilder::PrepareMultiHasedDict
  2309. : &TDictValueBuilder::PrepareHasedDict;
  2310. THashedDictFiller filler(std::bind(prepareFn, this, std::placeholders::_1));
  2311. return HolderFactory_.CreateDirectHashedDictHolder(
  2312. filler, Types_, IsTuple_, true, EncodeType_, Hash_, Equate_);
  2313. }
  2314. else {
  2315. auto prepareFn = (DictFlags_ & NUdf::TDictFlags::Multi)
  2316. ? &TDictValueBuilder::PrepareMultiSortedDict
  2317. : &TDictValueBuilder::PrepareSortedDict;
  2318. TSortedDictFiller filler(std::bind(prepareFn, this, std::placeholders::_1));
  2319. EDictSortMode mode = (DictFlags_ & NUdf::TDictFlags::Multi)
  2320. ? EDictSortMode::SortedUniqueAscending
  2321. : EDictSortMode::RequiresSorting;
  2322. return HolderFactory_.CreateDirectSortedDictHolder(filler, Types_, IsTuple_, mode, true,
  2323. EncodeType_, Compare_, Equate_);
  2324. }
  2325. }
  2326. private:
  2327. void PrepareMultiHasedDict(TValuesDictHashMap& map) {
  2328. TKeyPayloadPairVector localValues;
  2329. localValues.swap(Items_);
  2330. map.clear();
  2331. std::optional<TValuePacker> packer;
  2332. if (EncodeType_) {
  2333. packer.emplace(true, EncodeType_);
  2334. }
  2335. for (auto& value : localValues) {
  2336. auto key = value.first;
  2337. if (packer) {
  2338. key = MakeString(packer->Pack(key));
  2339. }
  2340. auto it = map.find(key);
  2341. if (it == map.end()) {
  2342. TDefaultListRepresentation emptyList;
  2343. auto newList = HolderFactory_.CreateDirectListHolder(
  2344. emptyList.Append(std::move(value.second)));
  2345. map.emplace(std::move(key), std::move(newList));
  2346. } else {
  2347. auto prevList = GetDefaultListRepresentation(it->second);
  2348. auto newList = HolderFactory_.CreateDirectListHolder(
  2349. prevList->Append(std::move(value.second)));
  2350. it->second = std::move(newList);
  2351. }
  2352. }
  2353. }
  2354. void PrepareHasedDict(TValuesDictHashMap& map) {
  2355. TKeyPayloadPairVector localValues;
  2356. localValues.swap(Items_);
  2357. map.clear();
  2358. std::optional<TValuePacker> packer;
  2359. if (EncodeType_) {
  2360. packer.emplace(true, EncodeType_);
  2361. }
  2362. for (auto& value : localValues) {
  2363. auto key = value.first;
  2364. if (packer) {
  2365. key = MakeString(packer->Pack(key));
  2366. }
  2367. map.emplace(std::move(key), std::move(value.second));
  2368. }
  2369. }
  2370. void PrepareMultiSortedDict(TKeyPayloadPairVector& values) {
  2371. TKeyPayloadPairVector localValues;
  2372. localValues.swap(Items_);
  2373. std::optional<TGenericPresortEncoder> packer;
  2374. if (EncodeType_) {
  2375. packer.emplace(EncodeType_);
  2376. for (auto& x : localValues) {
  2377. x.first = MakeString(packer->Encode(x.first, false));
  2378. }
  2379. }
  2380. StableSort(localValues.begin(), localValues.end(), TKeyPayloadPairLess(Types_, IsTuple_, Compare_));
  2381. TKeyPayloadPairVector groups;
  2382. groups.reserve(localValues.size());
  2383. if (!localValues.empty()) {
  2384. TDefaultListRepresentation currentList(std::move(localValues.begin()->second));
  2385. auto lastKey = std::move(localValues.begin()->first);
  2386. TValueEqual eqPredicate(Types_, IsTuple_, Equate_);
  2387. for (auto it = localValues.begin() + 1; it != localValues.end(); ++it) {
  2388. if (eqPredicate(lastKey, it->first)) {
  2389. currentList = currentList.Append(std::move(it->second));
  2390. } else {
  2391. auto payload = HolderFactory_.CreateDirectListHolder(std::move(currentList));
  2392. groups.emplace_back(std::move(lastKey), std::move(payload));
  2393. currentList = TDefaultListRepresentation(std::move(it->second));
  2394. lastKey = std::move(it->first);
  2395. }
  2396. }
  2397. auto payload = HolderFactory_.CreateDirectListHolder(std::move(currentList));
  2398. groups.emplace_back(std::move(lastKey), std::move(payload));
  2399. }
  2400. values.swap(groups);
  2401. }
  2402. void PrepareSortedDict(TKeyPayloadPairVector& values) {
  2403. Items_.swap(values);
  2404. std::optional<TGenericPresortEncoder> packer;
  2405. if (EncodeType_) {
  2406. packer.emplace(EncodeType_);
  2407. for (auto& x : values) {
  2408. x.first = MakeString(packer->Encode(x.first, false));
  2409. }
  2410. }
  2411. }
  2412. private:
  2413. const THolderFactory& HolderFactory_;
  2414. const TKeyTypes Types_;
  2415. const bool IsTuple_;
  2416. const ui32 DictFlags_;
  2417. TType* const EncodeType_;
  2418. const NUdf::IHash* Hash_;
  2419. const NUdf::IEquate* Equate_;
  2420. const NUdf::ICompare* Compare_;
  2421. TKeyPayloadPairVector Items_;
  2422. };
  2423. ///////////////////////////////////////////////////////////////////////////////
  2424. // TListValueBuilder
  2425. ///////////////////////////////////////////////////////////////////////////////
  2426. class TListValueBuilder: public NUdf::IListValueBuilder {
  2427. public:
  2428. explicit TListValueBuilder(const THolderFactory& HolderFactory)
  2429. : HolderFactory_(HolderFactory)
  2430. {}
  2431. // Destroys (moves out from) the element
  2432. IListValueBuilder& Add(NUdf::TUnboxedValue&& element) final {
  2433. List_.emplace_back(element);
  2434. return *this;
  2435. }
  2436. // Destroys (moves out from) the elements
  2437. IListValueBuilder& AddMany(const NUdf::TUnboxedValue* elements, size_t count) final {
  2438. std::copy_n(std::make_move_iterator(elements), count, std::back_inserter(List_));
  2439. return *this;
  2440. }
  2441. NUdf::TUnboxedValue Build() final {
  2442. if (List_.empty()) {
  2443. return HolderFactory_.GetEmptyContainerLazy();
  2444. }
  2445. return HolderFactory_.VectorAsVectorHolder(std::move(List_));
  2446. }
  2447. private:
  2448. const NMiniKQL::THolderFactory& HolderFactory_;
  2449. TUnboxedValueVector List_;
  2450. };
  2451. //////////////////////////////////////////////////////////////////////////////
  2452. // THolderFactory
  2453. //////////////////////////////////////////////////////////////////////////////
  2454. THolderFactory::THolderFactory(
  2455. TAllocState& allocState,
  2456. TMemoryUsageInfo& memInfo,
  2457. const IFunctionRegistry* functionRegistry)
  2458. : CurrentAllocState(&allocState)
  2459. , MemInfo(memInfo)
  2460. , FunctionRegistry(functionRegistry)
  2461. {
  2462. }
  2463. THolderFactory::~THolderFactory() {
  2464. if (EmptyContainer) {
  2465. CurrentAllocState->UnlockObject(*EmptyContainer);
  2466. }
  2467. }
  2468. NUdf::TUnboxedValuePod THolderFactory::GetEmptyContainerLazy() const {
  2469. if (!EmptyContainer) {
  2470. EmptyContainer.ConstructInPlace(
  2471. NUdf::TUnboxedValuePod(AllocateOn<TEmptyContainerHolder>(CurrentAllocState, &MemInfo)));
  2472. CurrentAllocState->LockObject(*EmptyContainer);
  2473. }
  2474. return *EmptyContainer;
  2475. }
  2476. NUdf::TUnboxedValuePod THolderFactory::CreateTypeHolder(TType* type) const {
  2477. return NUdf::TUnboxedValuePod(AllocateOn<TTypeHolder>(CurrentAllocState, &MemInfo, type));
  2478. }
  2479. NUdf::TUnboxedValuePod THolderFactory::CreateDirectListHolder(TDefaultListRepresentation&& items) const{
  2480. if (!items.GetLength())
  2481. return GetEmptyContainerLazy();
  2482. return NUdf::TUnboxedValuePod(AllocateOn<TDirectListHolder>(CurrentAllocState, &MemInfo, std::move(items)));
  2483. }
  2484. NUdf::TUnboxedValuePod THolderFactory::CreateDirectArrayHolder(ui64 size, NUdf::TUnboxedValue*& itemsPtr) const {
  2485. if (!size) {
  2486. itemsPtr = nullptr;
  2487. return GetEmptyContainerLazy();
  2488. }
  2489. const auto buffer = MKQLAllocFastWithSize(
  2490. sizeof(TDirectArrayHolderInplace) + size * sizeof(NUdf::TUnboxedValue), CurrentAllocState, EMemorySubPool::Default);
  2491. const auto h = ::new(buffer) TDirectArrayHolderInplace(&MemInfo, size);
  2492. auto res = NUdf::TUnboxedValuePod(h);
  2493. itemsPtr = h->GetPtr();
  2494. return res;
  2495. }
  2496. NUdf::TUnboxedValuePod THolderFactory::CreateArrowBlock(arrow::Datum&& datum) const {
  2497. return Create<TArrowBlock>(std::move(datum));
  2498. }
  2499. NUdf::TUnboxedValuePod THolderFactory::VectorAsArray(TUnboxedValueVector& values) const {
  2500. if (values.empty())
  2501. return GetEmptyContainerLazy();
  2502. NUdf::TUnboxedValue* itemsPtr = nullptr;
  2503. auto tuple = CreateDirectArrayHolder(values.size(), itemsPtr);
  2504. for (auto& value : values) {
  2505. *itemsPtr++ = std::move(value);
  2506. }
  2507. return tuple;
  2508. }
  2509. NUdf::TUnboxedValuePod THolderFactory::NewVectorHolder() const {
  2510. return NUdf::TUnboxedValuePod(new TVectorHolder(&MemInfo));
  2511. }
  2512. NUdf::TUnboxedValuePod THolderFactory::NewTemporaryVectorHolder() const {
  2513. return NUdf::TUnboxedValuePod(new TTemporaryVectorHolder(&MemInfo));
  2514. }
  2515. const NUdf::IHash* THolderFactory::GetHash(const TType& type, bool useIHash) const {
  2516. return useIHash ? HashRegistry.FindOrEmplace(type) : nullptr;
  2517. }
  2518. const NUdf::IEquate* THolderFactory::GetEquate(const TType& type, bool useIHash) const {
  2519. return useIHash ? EquateRegistry.FindOrEmplace(type) : nullptr;
  2520. }
  2521. const NUdf::ICompare* THolderFactory::GetCompare(const TType& type, bool useIHash) const {
  2522. return useIHash ? CompareRegistry.FindOrEmplace(type) : nullptr;
  2523. }
  2524. NUdf::TUnboxedValuePod THolderFactory::VectorAsVectorHolder(TUnboxedValueVector&& list) const {
  2525. return NUdf::TUnboxedValuePod(new TVectorHolder(&MemInfo, std::move(list)));
  2526. }
  2527. NUdf::TUnboxedValuePod THolderFactory::CloneArray(const NUdf::TUnboxedValuePod list, NUdf::TUnboxedValue*& items) const {
  2528. if (const auto size = list.GetListLength()) {
  2529. const auto ptr = list.GetElements();
  2530. if (ptr && list.UniqueBoxed()) {
  2531. items = const_cast<NUdf::TUnboxedValue*>(ptr);
  2532. return list;
  2533. } else {
  2534. const auto array = CreateDirectArrayHolder(size, items);
  2535. if (ptr) {
  2536. std::copy(ptr, ptr + size, items);
  2537. } else if (const auto& it = list.GetListIterator()) {
  2538. for (auto out = items; it.Next(*out++);)
  2539. continue;
  2540. }
  2541. list.DeleteUnreferenced();
  2542. return array;
  2543. }
  2544. } else {
  2545. items = nullptr;
  2546. return GetEmptyContainerLazy();
  2547. }
  2548. }
  2549. NUdf::TUnboxedValuePod THolderFactory::Cloned(const NUdf::TUnboxedValuePod& it) const
  2550. {
  2551. TDefaultListRepresentation result;
  2552. for (NUdf::TUnboxedValue item; it.Next(item);) {
  2553. result = result.Append(std::move(item));
  2554. }
  2555. return CreateDirectListHolder(std::move(result));
  2556. }
  2557. NUdf::TUnboxedValuePod THolderFactory::Reversed(const NUdf::TUnboxedValuePod& it) const
  2558. {
  2559. TDefaultListRepresentation result;
  2560. for (NUdf::TUnboxedValue item; it.Next(item);) {
  2561. result = result.Prepend(std::move(item));
  2562. }
  2563. return CreateDirectListHolder(std::move(result));
  2564. }
  2565. NUdf::TUnboxedValuePod THolderFactory::CreateLimitedList(
  2566. NUdf::IBoxedValuePtr&& parent,
  2567. TMaybe<ui64> skip, TMaybe<ui64> take,
  2568. TMaybe<ui64> knownLength) const
  2569. {
  2570. if (take && !take.GetRef()) {
  2571. return GetEmptyContainerLazy();
  2572. }
  2573. if (skip && !skip.GetRef()) {
  2574. skip = TMaybe<ui64>();
  2575. }
  2576. if (knownLength && skip) {
  2577. if (skip.GetRef() >= knownLength.GetRef()) {
  2578. return GetEmptyContainerLazy();
  2579. }
  2580. }
  2581. if (knownLength && take) {
  2582. if (take.GetRef() >= knownLength.GetRef() - skip.GetOrElse(0)) {
  2583. take = TMaybe<ui64>();
  2584. }
  2585. }
  2586. if (!skip && !take) {
  2587. return NUdf::TUnboxedValuePod(std::move(parent));
  2588. }
  2589. return NUdf::TUnboxedValuePod(AllocateOn<TLimitedList>(CurrentAllocState, &MemInfo, std::move(parent), skip, take));
  2590. }
  2591. NUdf::TUnboxedValuePod THolderFactory::ReverseList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const
  2592. {
  2593. auto boxed = list.AsBoxed();
  2594. if (auto res = NUdf::TBoxedValueAccessor::ReverseListImpl(*boxed, *builder)) {
  2595. return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
  2596. }
  2597. return Reversed(list.GetListIterator());
  2598. }
  2599. NUdf::TUnboxedValuePod THolderFactory::SkipList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const
  2600. {
  2601. auto boxed = list.AsBoxed();
  2602. if (auto res = NUdf::TBoxedValueAccessor::SkipListImpl(*boxed, *builder, count)) {
  2603. return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
  2604. }
  2605. TMaybe<ui64> knownLength;
  2606. if (list.HasFastListLength()) {
  2607. knownLength = list.GetListLength();
  2608. }
  2609. return CreateLimitedList(std::move(boxed), count, TMaybe<ui64>(), knownLength);
  2610. }
  2611. NUdf::TUnboxedValuePod THolderFactory::TakeList(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list, ui64 count) const
  2612. {
  2613. auto boxed = list.AsBoxed();
  2614. if (auto res = NUdf::TBoxedValueAccessor::TakeListImpl(*boxed, *builder, count)) {
  2615. return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
  2616. }
  2617. TMaybe<ui64> knownLength;
  2618. if (list.HasFastListLength()) {
  2619. knownLength = list.GetListLength();
  2620. }
  2621. return CreateLimitedList(std::move(boxed), TMaybe<ui64>(), count, knownLength);
  2622. }
  2623. NUdf::TUnboxedValuePod THolderFactory::ToIndexDict(const NUdf::IValueBuilder* builder, const NUdf::TUnboxedValuePod list) const
  2624. {
  2625. auto boxed = list.AsBoxed();
  2626. if (auto res = NUdf::TBoxedValueAccessor::ToIndexDictImpl(*boxed, *builder)) {
  2627. return NUdf::TUnboxedValuePod(std::move(boxed = std::move(res)));
  2628. }
  2629. return Cloned(list.GetListIterator());
  2630. }
  2631. template<bool IsStream>
  2632. NUdf::TUnboxedValuePod THolderFactory::Collect(NUdf::TUnboxedValuePod list) const {
  2633. const auto boxed = list.AsBoxed(); // Only for release on exit.
  2634. if (!IsStream && list.HasFastListLength()) {
  2635. auto size = list.GetListLength();
  2636. NUdf::TUnboxedValue* items = nullptr;
  2637. const auto result = CreateDirectArrayHolder(size, items);
  2638. TThresher<IsStream>::DoForEachItem(list,
  2639. [&items] (NUdf::TUnboxedValue&& item) {
  2640. *items++ = std::move(item);
  2641. }
  2642. );
  2643. return result;
  2644. } else {
  2645. TDefaultListRepresentation res;
  2646. TThresher<IsStream>::DoForEachItem(list,
  2647. [&res] (NUdf::TUnboxedValue&& item) {
  2648. res = res.Append(std::move(item));
  2649. }
  2650. );
  2651. return CreateDirectListHolder(std::move(res));
  2652. }
  2653. }
  2654. template NUdf::TUnboxedValuePod THolderFactory::Collect<true>(NUdf::TUnboxedValuePod list) const;
  2655. template NUdf::TUnboxedValuePod THolderFactory::Collect<false>(NUdf::TUnboxedValuePod list) const;
  2656. NUdf::TUnboxedValuePod THolderFactory::LazyList(NUdf::TUnboxedValuePod list) const {
  2657. return NUdf::TUnboxedValuePod(AllocateOn<TLazyListDecorator>(CurrentAllocState, &MemInfo, list.AsBoxed()));;
  2658. }
  2659. NUdf::TUnboxedValuePod THolderFactory::Append(NUdf::TUnboxedValuePod list, NUdf::TUnboxedValuePod last) const {
  2660. const auto boxed = list.AsBoxed();
  2661. TDefaultListRepresentation resList;
  2662. if (const auto leftRepr = reinterpret_cast<const TDefaultListRepresentation*>(NUdf::TBoxedValueAccessor::GetListRepresentation(*boxed))) {
  2663. resList = std::move(*leftRepr);
  2664. } else {
  2665. TThresher<false>::DoForEachItem(list,
  2666. [&resList] (NUdf::TUnboxedValue&& item) {
  2667. resList = resList.Append(std::move(item));
  2668. }
  2669. );
  2670. }
  2671. resList = resList.Append(std::move(last));
  2672. return CreateDirectListHolder(std::move(resList));
  2673. }
  2674. NUdf::TUnboxedValuePod THolderFactory::Prepend(NUdf::TUnboxedValuePod first, NUdf::TUnboxedValuePod list) const {
  2675. const auto boxed = list.AsBoxed();
  2676. TDefaultListRepresentation resList;
  2677. if (const auto rightRepr = reinterpret_cast<const TDefaultListRepresentation*>(NUdf::TBoxedValueAccessor::GetListRepresentation(*boxed))) {
  2678. resList = *rightRepr;
  2679. } else {
  2680. TThresher<false>::DoForEachItem(list,
  2681. [&resList] (NUdf::TUnboxedValue&& item) {
  2682. resList = resList.Append(std::move(item));
  2683. }
  2684. );
  2685. }
  2686. resList = resList.Prepend(std::move(first));
  2687. return CreateDirectListHolder(std::move(resList));
  2688. }
  2689. NUdf::TUnboxedValuePod THolderFactory::ExtendStream(NUdf::TUnboxedValue* data, ui64 size) const {
  2690. if (!data || !size) {
  2691. return GetEmptyContainerLazy();
  2692. }
  2693. TUnboxedValueVector values(size);
  2694. std::move(data, data + size, values.begin());
  2695. return Create<TExtendStreamValue>(std::move(values));
  2696. }
  2697. template<>
  2698. NUdf::TUnboxedValuePod THolderFactory::ExtendList<true>(NUdf::TUnboxedValue* data, ui64 size) const {
  2699. if (!data || !size) {
  2700. return GetEmptyContainerLazy();
  2701. }
  2702. TUnboxedValueVector values;
  2703. values.reserve(size);
  2704. std::transform(data, data + size, std::back_inserter(values), [this](NUdf::TUnboxedValue& stream){ return Create<TForwardListValue>(std::move(stream)); });
  2705. return Create<TExtendListValue>(std::move(values));
  2706. }
  2707. template<>
  2708. NUdf::TUnboxedValuePod THolderFactory::ExtendList<false>(NUdf::TUnboxedValue* data, ui64 size) const {
  2709. if (!data || !size) {
  2710. return GetEmptyContainerLazy();
  2711. }
  2712. using TElementsAndSize = std::tuple<const NUdf::TUnboxedValuePod*, ui64, ui64>;
  2713. TSmallVec<TElementsAndSize, TMKQLAllocator<TElementsAndSize>> elements;
  2714. elements.reserve(size);
  2715. for (ui64 i = 0ULL; i < size; ++i) {
  2716. if (const auto ptr = data[i].GetElements()) {
  2717. if (const auto length = data[i].GetListLength()) {
  2718. elements.emplace_back(ptr, length, i);
  2719. }
  2720. } else {
  2721. TUnboxedValueVector values(size);
  2722. std::move(data, data + size, values.begin());
  2723. return Create<TExtendListValue>(std::move(values));
  2724. }
  2725. }
  2726. const auto total = std::accumulate(elements.cbegin(), elements.cend(), 0ULL, [](ui64 s, TElementsAndSize i) { return s + std::get<1U>(i); });
  2727. if (!total) {
  2728. std::fill_n(data, size, NUdf::TUnboxedValue());
  2729. return GetEmptyContainerLazy();
  2730. }
  2731. if (1U == elements.size()) {
  2732. const auto result = data[std::get<2U>(elements.front())].Release();
  2733. std::fill_n(data, size, NUdf::TUnboxedValue());
  2734. return result;
  2735. }
  2736. auto it = elements.cbegin();
  2737. if (const auto first = GetDefaultListRepresentation(data[std::get<2U>(*it++)])) {
  2738. TDefaultListRepresentation list(*first);
  2739. while (elements.cend() != it) {
  2740. const auto& e = *it++;
  2741. if (const auto repr = GetDefaultListRepresentation(data[std::get<2U>(e)])) {
  2742. list = list.Extend(*repr);
  2743. } else {
  2744. std::for_each(std::get<0U>(e), std::get<0U>(e) + std::get<1U>(e),
  2745. [&](NUdf::TUnboxedValue item) {
  2746. list = list.Append(std::move(item));
  2747. }
  2748. );
  2749. }
  2750. }
  2751. std::fill_n(data, size, NUdf::TUnboxedValue());
  2752. return CreateDirectListHolder(std::move(list));
  2753. } else {
  2754. NUdf::TUnboxedValue *items = nullptr;
  2755. const auto result = CreateDirectArrayHolder(total, items);
  2756. for (const auto& i : elements) {
  2757. std::copy_n(std::get<0U>(i), std::get<1U>(i), items);
  2758. items += std::get<1U>(i);
  2759. }
  2760. std::fill_n(data, size, NUdf::TUnboxedValue());
  2761. return result;
  2762. }
  2763. }
  2764. NUdf::TUnboxedValuePod THolderFactory::CreateVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const {
  2765. if (item.TryMakeVariant(index))
  2766. return item;
  2767. return CreateBoxedVariantHolder(std::move(item), index);
  2768. }
  2769. NUdf::TUnboxedValuePod THolderFactory::CreateBoxedVariantHolder(NUdf::TUnboxedValuePod item, ui32 index) const {
  2770. return NUdf::TUnboxedValuePod(AllocateOn<TVariantHolder>(CurrentAllocState, &MemInfo, std::move(item), index));
  2771. }
  2772. NUdf::TUnboxedValuePod THolderFactory::CreateIteratorOverList(NUdf::TUnboxedValuePod list) const {
  2773. return NUdf::TUnboxedValuePod(AllocateOn<TListIteratorHolder>(CurrentAllocState, &MemInfo, list));
  2774. }
  2775. NUdf::TUnboxedValuePod THolderFactory::CreateForwardList(NUdf::TUnboxedValuePod stream) const {
  2776. return NUdf::TUnboxedValuePod(AllocateOn<TForwardListValue>(CurrentAllocState, &MemInfo, stream));
  2777. }
  2778. NUdf::TUnboxedValuePod THolderFactory::CreateDirectSortedSetHolder(
  2779. TSortedSetFiller filler,
  2780. const TKeyTypes& types,
  2781. bool isTuple,
  2782. EDictSortMode mode,
  2783. bool eagerFill,
  2784. TType* encodedType,
  2785. const NUdf::ICompare* compare,
  2786. const NUdf::IEquate* equate) const
  2787. {
  2788. return NUdf::TUnboxedValuePod(AllocateOn<TSortedSetHolder>(CurrentAllocState, &MemInfo,
  2789. filler, types, isTuple, mode, eagerFill, encodedType, compare, equate, *this));
  2790. }
  2791. NUdf::TUnboxedValuePod THolderFactory::CreateDirectSortedDictHolder(
  2792. TSortedDictFiller filler,
  2793. const TKeyTypes& types,
  2794. bool isTuple,
  2795. EDictSortMode mode,
  2796. bool eagerFill,
  2797. TType* encodedType,
  2798. const NUdf::ICompare* compare,
  2799. const NUdf::IEquate* equate) const
  2800. {
  2801. return NUdf::TUnboxedValuePod(AllocateOn<TSortedDictHolder>(CurrentAllocState, &MemInfo,
  2802. filler, types, isTuple, mode, eagerFill, encodedType, compare, equate, *this));
  2803. }
  2804. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedDictHolder(
  2805. THashedDictFiller filler,
  2806. const TKeyTypes& types,
  2807. bool isTuple,
  2808. bool eagerFill,
  2809. TType* encodedType,
  2810. const NUdf::IHash* hash,
  2811. const NUdf::IEquate* equate) const
  2812. {
  2813. return NUdf::TUnboxedValuePod(AllocateOn<THashedDictHolder>(CurrentAllocState, &MemInfo,
  2814. filler, types, isTuple, eagerFill, encodedType, hash, equate, *this));
  2815. }
  2816. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSetHolder(
  2817. THashedSetFiller filler,
  2818. const TKeyTypes& types,
  2819. bool isTuple,
  2820. bool eagerFill,
  2821. TType* encodedType,
  2822. const NUdf::IHash* hash,
  2823. const NUdf::IEquate* equate) const {
  2824. return NUdf::TUnboxedValuePod(AllocateOn<THashedSetHolder>(CurrentAllocState, &MemInfo,
  2825. filler, types, isTuple, eagerFill, encodedType, hash, equate, *this));
  2826. }
  2827. template <typename T, bool OptionalKey>
  2828. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedSetHolder(
  2829. TValuesDictHashSingleFixedSet<T>&& set, bool hasNull) const {
  2830. return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedSetHolder<T, OptionalKey>>(CurrentAllocState, &MemInfo, std::move(set), hasNull));
  2831. }
  2832. #define DEFINE_HASHED_SINGLE_FIXED_SET_OPT(xType) \
  2833. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedSetHolder<xType, true> \
  2834. (TValuesDictHashSingleFixedSet<xType>&& set, bool hasNull) const;
  2835. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_SET_OPT)
  2836. #undef DEFINE_HASHED_SINGLE_FIXED_SET_OPT
  2837. #define DEFINE_HASHED_SINGLE_FIXED_SET_NONOPT(xType) \
  2838. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedSetHolder<xType, false> \
  2839. (TValuesDictHashSingleFixedSet<xType>&& set, bool hasNull) const;
  2840. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_SET_NONOPT)
  2841. #undef DEFINE_HASHED_SINGLE_FIXED_SET_NONOPT
  2842. template <typename T, bool OptionalKey>
  2843. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactSetHolder(
  2844. TValuesDictHashSingleFixedCompactSet<T>&& set, bool hasNull) const {
  2845. return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedCompactSetHolder<T, OptionalKey>>(CurrentAllocState, &MemInfo, std::move(set), hasNull));
  2846. }
  2847. #define DEFINE_HASHED_SINGLE_FIXED_COMPACT_SET_OPT(xType) \
  2848. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactSetHolder<xType, true> \
  2849. (TValuesDictHashSingleFixedCompactSet<xType>&& set, bool hasNull) const;
  2850. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_COMPACT_SET_OPT)
  2851. #undef DEFINE_HASHED_SINGLE_FIXED_COMPACT_SET_OPT
  2852. #define DEFINE_HASHED_SINGLE_FIXED_COMPACT_SET_NONOPT(xType) \
  2853. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactSetHolder<xType, false> \
  2854. (TValuesDictHashSingleFixedCompactSet<xType>&& set, bool hasNull) const;
  2855. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_COMPACT_SET_NONOPT)
  2856. #undef DEFINE_HASHED_SINGLE_FIXED_COMPACT_SET_NONOPT
  2857. template <typename T, bool OptionalKey>
  2858. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedMapHolder(
  2859. TValuesDictHashSingleFixedMap<T>&& map, std::optional<NUdf::TUnboxedValue>&& nullPayload) const {
  2860. return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedMapHolder<T, OptionalKey>>(CurrentAllocState, &MemInfo, std::move(map), std::move(nullPayload)));
  2861. }
  2862. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedCompactSetHolder(
  2863. TValuesDictHashCompactSet&& set, TPagedArena&& pool, TType* keyType, TComputationContext* ctx) const {
  2864. return NUdf::TUnboxedValuePod(AllocateOn<THashedCompactSetHolder>(CurrentAllocState, &MemInfo, std::move(set), std::move(pool), keyType, ctx));
  2865. }
  2866. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedCompactMapHolder(
  2867. TValuesDictHashCompactMap&& map, TPagedArena&& pool, TType* keyType, TType* payloadType,
  2868. TComputationContext* ctx) const {
  2869. return NUdf::TUnboxedValuePod(AllocateOn<THashedCompactMapHolder>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), keyType, payloadType, ctx));
  2870. }
  2871. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedCompactMultiMapHolder(
  2872. TValuesDictHashCompactMultiMap&& map, TPagedArena&& pool, TType* keyType, TType* payloadType,
  2873. TComputationContext* ctx) const {
  2874. return NUdf::TUnboxedValuePod(AllocateOn<THashedCompactMultiMapHolder>(CurrentAllocState, &MemInfo, std::move(map), std::move(pool), keyType, payloadType, ctx));
  2875. }
  2876. template <typename T, bool OptionalKey>
  2877. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMapHolder(
  2878. TValuesDictHashSingleFixedCompactMap<T>&& map, std::optional<ui64>&& nullPayload, TPagedArena&& pool, TType* payloadType,
  2879. TComputationContext* ctx) const {
  2880. return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedCompactMapHolder<T, OptionalKey>>(CurrentAllocState, &MemInfo,
  2881. std::move(map), std::move(nullPayload), std::move(pool), payloadType, ctx));
  2882. }
  2883. template <typename T, bool OptionalKey>
  2884. NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMultiMapHolder(
  2885. TValuesDictHashSingleFixedCompactMultiMap<T>&& map, std::vector<ui64>&& nullPayloads, TPagedArena&& pool, TType* payloadType,
  2886. TComputationContext* ctx) const {
  2887. return NUdf::TUnboxedValuePod(AllocateOn<THashedSingleFixedCompactMultiMapHolder<T, OptionalKey>>(CurrentAllocState, &MemInfo,
  2888. std::move(map), std::move(nullPayloads), std::move(pool), payloadType, ctx));
  2889. }
  2890. NUdf::IDictValueBuilder::TPtr THolderFactory::NewDict(
  2891. const NUdf::TType* dictType,
  2892. ui32 flags) const
  2893. {
  2894. TType* type = const_cast<TType*>(static_cast<const TType*>(dictType));
  2895. TType* keyType = AS_TYPE(TDictType, type)->GetKeyType();
  2896. TKeyTypes types;
  2897. bool encoded;
  2898. bool isTuple;
  2899. bool useIHash;
  2900. GetDictionaryKeyTypes(keyType, types, isTuple, encoded, useIHash);
  2901. return new TDictValueBuilder(*this, types, isTuple, flags, encoded ? keyType : nullptr,
  2902. GetHash(*keyType, useIHash), GetEquate(*keyType, useIHash),
  2903. GetCompare(*keyType, useIHash));
  2904. }
  2905. NUdf::IListValueBuilder::TPtr THolderFactory::NewList() const {
  2906. return new TListValueBuilder(*this);
  2907. }
  2908. #define DEFINE_HASHED_SINGLE_FIXED_MAP_OPT(xType) \
  2909. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedMapHolder<xType, true> \
  2910. (TValuesDictHashSingleFixedMap<xType>&& map, std::optional<NUdf::TUnboxedValue>&& nullPayload) const;
  2911. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_MAP_OPT)
  2912. #undef DEFINE_HASHED_SINGLE_FIXED_MAP_OPT
  2913. #define DEFINE_HASHED_SINGLE_FIXED_MAP_NONOPT(xType) \
  2914. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedMapHolder<xType, false> \
  2915. (TValuesDictHashSingleFixedMap<xType>&& map, std::optional<NUdf::TUnboxedValue>&& nullPayload) const;
  2916. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_MAP_NONOPT)
  2917. #undef DEFINE_HASHED_SINGLE_FIXED_MAP_NONOPT
  2918. #define DEFINE_HASHED_SINGLE_FIXED_COMPACT_MAP_OPT(xType) \
  2919. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMapHolder<xType, true> \
  2920. (TValuesDictHashSingleFixedCompactMap<xType>&& map, std::optional<ui64>&& nullPayload, TPagedArena&& pool, TType* payloadType, \
  2921. TComputationContext* ctx) const;
  2922. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_COMPACT_MAP_OPT)
  2923. #undef DEFINE_HASHED_SINGLE_FIXED_COMPACT_MAP_OPT
  2924. #define DEFINE_HASHED_SINGLE_FIXED_COMPACT_MAP_NONOPT(xType) \
  2925. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMapHolder<xType, false> \
  2926. (TValuesDictHashSingleFixedCompactMap<xType>&& map, std::optional<ui64>&& nullPayload, TPagedArena&& pool, TType* payloadType, \
  2927. TComputationContext* ctx) const;
  2928. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_COMPACT_MAP_NONOPT)
  2929. #undef DEFINE_HASHED_SINGLE_FIXED_COMPACT_MAP_NONOPT
  2930. #define DEFINE_HASHED_SINGLE_FIXED_COMPACT_MULTI_MAP_OPT(xType) \
  2931. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMultiMapHolder<xType, true> \
  2932. (TValuesDictHashSingleFixedCompactMultiMap<xType>&& map, std::vector<ui64>&& nullPayloads, TPagedArena&& pool, TType* payloadType, \
  2933. TComputationContext* ctx) const;
  2934. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_COMPACT_MULTI_MAP_OPT)
  2935. #undef DEFINE_HASHED_SINGLE_FIXED_COMPACT_MULTI_MAP_OPT
  2936. #define DEFINE_HASHED_SINGLE_FIXED_COMPACT_MULTI_MAP_NONOPT(xType) \
  2937. template NUdf::TUnboxedValuePod THolderFactory::CreateDirectHashedSingleFixedCompactMultiMapHolder<xType, false> \
  2938. (TValuesDictHashSingleFixedCompactMultiMap<xType>&& map, std::vector<ui64>&& nullPayloads, TPagedArena&& pool, TType* payloadType, \
  2939. TComputationContext* ctx) const;
  2940. KNOWN_PRIMITIVE_VALUE_TYPES(DEFINE_HASHED_SINGLE_FIXED_COMPACT_MULTI_MAP_NONOPT)
  2941. #undef DEFINE_HASHED_SINGLE_FIXED_COMPACT_MULTI_MAP_NONOPT
  2942. void GetDictionaryKeyTypes(const TType* keyType, TKeyTypes& types, bool& isTuple, bool& encoded, bool& useIHash, bool expandTuple) {
  2943. isTuple = false;
  2944. encoded = false;
  2945. useIHash = false;
  2946. types.clear();
  2947. if (!keyType->IsPresortSupported()) {
  2948. useIHash = true;
  2949. return;
  2950. }
  2951. const bool isOptional = keyType->IsOptional();
  2952. if (isOptional) {
  2953. keyType = AS_TYPE(TOptionalType, keyType)->GetItemType();
  2954. }
  2955. if (expandTuple && keyType->IsTuple()) {
  2956. auto tuple = AS_TYPE(TTupleType, keyType);
  2957. for (ui32 i = 0; i < tuple->GetElementsCount(); ++i) {
  2958. bool isOptional;
  2959. auto unpacked = UnpackOptional(tuple->GetElementType(i), isOptional);
  2960. if (!unpacked->IsData()) {
  2961. encoded = true;
  2962. break;
  2963. }
  2964. types.emplace_back(*AS_TYPE(TDataType, unpacked)->GetDataSlot(), isOptional);
  2965. }
  2966. if (!encoded) {
  2967. isTuple = true;
  2968. }
  2969. } else if (keyType->IsData()) {
  2970. types.emplace_back(*AS_TYPE(TDataType, keyType)->GetDataSlot(), isOptional);
  2971. } else {
  2972. encoded = true;
  2973. }
  2974. if (encoded) {
  2975. types.clear();
  2976. types.emplace_back(NUdf::EDataSlot::String, false);
  2977. return;
  2978. }
  2979. }
  2980. TPlainContainerCache::TPlainContainerCache() {
  2981. Clear();
  2982. }
  2983. void TPlainContainerCache::Clear() {
  2984. Cached.fill(NUdf::TUnboxedValue());
  2985. CachedItems.fill(nullptr);
  2986. }
  2987. NUdf::TUnboxedValuePod TPlainContainerCache::NewArray(const THolderFactory& factory, ui64 size, NUdf::TUnboxedValue*& items) {
  2988. if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
  2989. CacheIndex ^= 1U;
  2990. if (!CachedItems[CacheIndex] || !Cached[CacheIndex].UniqueBoxed()) {
  2991. Cached[CacheIndex] = factory.CreateDirectArrayHolder(size, CachedItems[CacheIndex]);
  2992. items = CachedItems[CacheIndex];
  2993. return static_cast<const NUdf::TUnboxedValuePod&>(Cached[CacheIndex]);
  2994. }
  2995. }
  2996. items = CachedItems[CacheIndex];
  2997. std::fill_n(items, size, NUdf::TUnboxedValue());
  2998. return static_cast<const NUdf::TUnboxedValuePod&>(Cached[CacheIndex]);
  2999. }
  3000. } // namespace NMiniKQL
  3001. } // namespace NKikimr