mkql_pack_bc.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include <util/generic/buffer.h>
  2. #include <yql/essentials/public/udf/udf_value.h>
  3. #include <yql/essentials/minikql/pack_num.h>
  4. #include <library/cpp/packedtypes/zigzag.h>
  5. #include <yql/essentials/minikql/defs.h>
  6. #include "mkql_optional_usage_mask.h"
  7. using namespace NKikimr;
  8. namespace NDetails {
  9. void PackUInt64(ui64 pos, ui64 val, TBuffer& buf) {
  10. const auto actual = Pack64(val, buf.Data() + pos);
  11. buf.Chop(pos + actual, MAX_PACKED64_SIZE - actual);
  12. }
  13. void PackUInt64(ui64 val, TBuffer& buf) {
  14. size_t off = buf.Size();
  15. buf.Advance(MAX_PACKED64_SIZE);
  16. buf.EraseBack(MAX_PACKED64_SIZE - Pack64(val, buf.Data() + off));
  17. }
  18. void PackInt64(i64 val, TBuffer& buf) {
  19. PackUInt64(ZigZagEncode(val), buf);
  20. }
  21. void PackUInt32(ui32 val, TBuffer& buf) {
  22. size_t off = buf.Size();
  23. buf.Advance(MAX_PACKED32_SIZE);
  24. buf.EraseBack(MAX_PACKED32_SIZE - Pack32(val, buf.Data() + off));
  25. }
  26. void PackInt32(i32 val, TBuffer& buf) {
  27. PackUInt32(ZigZagEncode(val), buf);
  28. }
  29. ui64 UnpackUInt64(TStringBuf& buf) {
  30. ui64 res = 0;
  31. size_t read = Unpack64(buf.data(), buf.length(), res);
  32. MKQL_ENSURE(read, "Bad ui64 packed data");
  33. buf.Skip(read);
  34. return res;
  35. }
  36. i64 UnpackInt64(TStringBuf& buf) {
  37. return ZigZagDecode(UnpackUInt64(buf));
  38. }
  39. ui32 UnpackUInt32(TStringBuf& buf) {
  40. ui32 res = 0;
  41. size_t read = Unpack32(buf.data(), buf.length(), res);
  42. MKQL_ENSURE(read, "Bad ui32 packed data");
  43. buf.Skip(read);
  44. return res;
  45. }
  46. i32 UnpackInt32(TStringBuf& buf) {
  47. return ZigZagDecode(UnpackUInt32(buf));
  48. }
  49. template <typename T>
  50. void PutRawData(T val, TBuffer& buf) {
  51. buf.Append(reinterpret_cast<const char*>(&val), sizeof(T));
  52. }
  53. template <typename T>
  54. T GetRawData(TStringBuf& buf) {
  55. MKQL_ENSURE(sizeof(T) <= buf.size(), "Bad packed data. Buffer too small");
  56. T val = 0;
  57. std::memcpy(&val, buf.data(), sizeof(T));
  58. buf.Skip(sizeof(T));
  59. return val;
  60. }
  61. }
  62. extern "C" void GetElement(const TRawUV* value, ui32 index, TRawUV* item) {
  63. const auto result(reinterpret_cast<const NUdf::TUnboxedValuePod*>(value)->GetElement(index));
  64. *item = reinterpret_cast<const TRawUV&>(result);
  65. }
  66. extern "C" bool FetchNextItem(const TRawUV* value, TRawUV* item) {
  67. NUdf::TUnboxedValue fetch;
  68. if (NUdf::EFetchStatus::Finish == reinterpret_cast<const NUdf::TUnboxedValuePod*>(value)->Fetch(fetch))
  69. return false;
  70. *item = reinterpret_cast<TRawUV&>(fetch);
  71. return true;
  72. }
  73. extern "C" bool NextListItem(TRawUV* value, TRawUV* item) {
  74. NUdf::TUnboxedValue next;
  75. const auto v = reinterpret_cast<NUdf::TUnboxedValuePod*>(value);
  76. if (!v->Next(next)) {
  77. v->DeleteUnreferenced();
  78. return false;
  79. }
  80. *item = reinterpret_cast<TRawUV&>(next);
  81. return true;
  82. }
  83. extern "C" bool NextDictItem(TRawUV* value, TRawUV* first, TRawUV* second) {
  84. NUdf::TUnboxedValue key, payload;
  85. const auto v = reinterpret_cast<NUdf::TUnboxedValuePod*>(value);
  86. if (!v->NextPair(key, payload)) {
  87. v->DeleteUnreferenced();
  88. return false;
  89. }
  90. *first = reinterpret_cast<TRawUV&>(key);
  91. *second = reinterpret_cast<TRawUV&>(payload);
  92. return true;
  93. }
  94. extern "C" void PackString(const TRawUV* value, ui64* buffer) {
  95. const auto& stringRef = reinterpret_cast<const NUdf::TUnboxedValue*>(value)->AsStringRef();
  96. NDetails::PackUInt32(stringRef.Size(), *reinterpret_cast<TBuffer*>(buffer));
  97. reinterpret_cast<TBuffer*>(buffer)->Append(stringRef.Data(), stringRef.Size());
  98. }
  99. extern "C" void PackStringData(const TRawUV* value, ui64* buffer) {
  100. const auto& stringRef = reinterpret_cast<const NUdf::TUnboxedValue*>(value)->AsStringRef();
  101. reinterpret_cast<TBuffer*>(buffer)->Append(stringRef.Data(), stringRef.Size());
  102. }
  103. extern "C" void PackBool(const TRawUV* value, ui64* buffer) {
  104. NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<bool>(), *reinterpret_cast<TBuffer*>(buffer));
  105. }
  106. extern "C" void PackByte(const TRawUV* value, ui64* buffer) {
  107. NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<ui8>(), *reinterpret_cast<TBuffer*>(buffer));
  108. }
  109. extern "C" void PackInt32(const TRawUV* value, ui64* buffer) {
  110. NDetails::PackInt32(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<i32>(), *reinterpret_cast<TBuffer*>(buffer));
  111. }
  112. extern "C" void PackUInt32(const TRawUV* value, ui64* buffer) {
  113. NDetails::PackUInt32(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<ui32>(), *reinterpret_cast<TBuffer*>(buffer));
  114. }
  115. extern "C" void PackInt64(const TRawUV* value, ui64* buffer) {
  116. NDetails::PackInt64(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<i64>(), *reinterpret_cast<TBuffer*>(buffer));
  117. }
  118. extern "C" void PackUInt64(const TRawUV* value, ui64* buffer) {
  119. NDetails::PackUInt64(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<ui64>(), *reinterpret_cast<TBuffer*>(buffer));
  120. }
  121. extern "C" void PackFloat(const TRawUV* value, ui64* buffer) {
  122. NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<float>(), *reinterpret_cast<TBuffer*>(buffer));
  123. }
  124. extern "C" void PackDouble(const TRawUV* value, ui64* buffer) {
  125. NDetails::PutRawData(reinterpret_cast<const NUdf::TUnboxedValue*>(value)->Get<double>(), *reinterpret_cast<TBuffer*>(buffer));
  126. }
  127. extern "C" ui32 GetVariantItem(const TRawUV* value, TRawUV* item, ui64* buffer) {
  128. const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
  129. const ui32 index = v->GetVariantIndex();
  130. NDetails::PackUInt32(index, *reinterpret_cast<TBuffer*>(buffer));
  131. const auto result(v->GetVariantItem());
  132. *item = reinterpret_cast<const TRawUV&>(result);
  133. return index;
  134. }
  135. extern "C" bool GetListIterator(const TRawUV* value, TRawUV* item, ui64* buffer) {
  136. const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
  137. const auto size = v->GetListLength();
  138. NDetails::PackUInt64(size, *reinterpret_cast<TBuffer*>(buffer));
  139. if (!size)
  140. return false;
  141. const auto result(v->GetListIterator().Release());
  142. *item = reinterpret_cast<const TRawUV&>(result);
  143. return true;
  144. }
  145. extern "C" bool GetDictIterator(const TRawUV* value, TRawUV* item, ui64* buffer) {
  146. const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
  147. const auto size = v->GetDictLength();
  148. NDetails::PackUInt64(size, *reinterpret_cast<TBuffer*>(buffer));
  149. if (!size)
  150. return false;
  151. const auto result(v->GetDictIterator().Release());
  152. *item = reinterpret_cast<const TRawUV&>(result);
  153. return true;
  154. }
  155. extern "C" bool GetOptionalValue(const TRawUV* value, TRawUV* item, ui64* mask) {
  156. const auto v = reinterpret_cast<const NUdf::TUnboxedValuePod*>(value);
  157. const bool has = bool(*v);
  158. reinterpret_cast<NMiniKQL::NDetails::TOptionalUsageMask*>(mask)->SetNextEmptyOptional(!*v);
  159. if (has) {
  160. const auto result(v->GetOptionalValue());
  161. *item = reinterpret_cast<const TRawUV&>(result);
  162. }
  163. return has;
  164. }