mkql_custom_list.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "mkql_custom_list.h"
  2. namespace NKikimr {
  3. namespace NMiniKQL {
  4. TForwardListValue::TForwardListValue(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream)
  5. : TCustomListValue(memInfo)
  6. , Stream(std::move(stream))
  7. {
  8. MKQL_ENSURE(Stream, "Empty stream.");
  9. }
  10. TForwardListValue::TIterator::TIterator(TMemoryUsageInfo* memInfo, NUdf::TUnboxedValue&& stream)
  11. : TComputationValue(memInfo), Stream(std::move(stream))
  12. {}
  13. bool TForwardListValue::TIterator::Next(NUdf::TUnboxedValue& value) {
  14. const auto status = Stream.Fetch(value);
  15. MKQL_ENSURE(status != NUdf::EFetchStatus::Yield, "Unexpected stream status.");
  16. return status == NUdf::EFetchStatus::Ok;
  17. }
  18. NUdf::TUnboxedValue TForwardListValue::GetListIterator() const {
  19. MKQL_ENSURE(Stream, "Second pass for ForwardList");
  20. return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), std::move(Stream)));
  21. }
  22. TExtendListValue::TExtendListValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists)
  23. : TCustomListValue(memInfo)
  24. , Lists(std::move(lists))
  25. {
  26. MKQL_MEM_TAKE(memInfo, Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
  27. Y_ASSERT(!Lists.empty());
  28. }
  29. TExtendListValue::TIterator::TIterator(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& iters)
  30. : TComputationValue(memInfo)
  31. , Iters(std::move(iters))
  32. , Index(0)
  33. {
  34. MKQL_MEM_TAKE(memInfo, Iters.data(), Iters.capacity() * sizeof(NUdf::TUnboxedValue));
  35. }
  36. TExtendListValue::TIterator::~TIterator()
  37. {
  38. MKQL_MEM_RETURN(GetMemInfo(), Iters.data(), Iters.capacity() * sizeof(NUdf::TUnboxedValue));
  39. }
  40. bool TExtendListValue::TIterator::Next(NUdf::TUnboxedValue& value) {
  41. for (; Index < Iters.size(); ++Index) {
  42. if (Iters[Index].Next(value)) {
  43. return true;
  44. }
  45. }
  46. return false;
  47. }
  48. bool TExtendListValue::TIterator::Skip() {
  49. for (; Index < Iters.size(); ++Index) {
  50. if (Iters[Index].Skip()) {
  51. return true;
  52. }
  53. }
  54. return false;
  55. }
  56. NUdf::TUnboxedValue TExtendListValue::GetListIterator() const {
  57. TUnboxedValueVector iters;
  58. iters.reserve(Lists.size());
  59. for (const auto& list : Lists) {
  60. iters.emplace_back(list.GetListIterator());
  61. }
  62. return NUdf::TUnboxedValuePod(new TIterator(GetMemInfo(), std::move(iters)));
  63. }
  64. TExtendListValue::~TExtendListValue() {
  65. MKQL_MEM_RETURN(GetMemInfo(), Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
  66. }
  67. ui64 TExtendListValue::GetListLength() const {
  68. if (!Length) {
  69. ui64 length = 0ULL;
  70. for (const auto& list : Lists) {
  71. ui64 partialLength = list.GetListLength();
  72. length += partialLength;
  73. }
  74. Length = length;
  75. }
  76. return *Length;
  77. }
  78. bool TExtendListValue::HasListItems() const {
  79. if (!HasItems) {
  80. for (const auto& list : Lists) {
  81. if (list.HasListItems()) {
  82. HasItems = true;
  83. break;
  84. }
  85. }
  86. if (!HasItems) {
  87. HasItems = false;
  88. }
  89. }
  90. return *HasItems;
  91. }
  92. TExtendStreamValue::TExtendStreamValue(TMemoryUsageInfo* memInfo, TUnboxedValueVector&& lists)
  93. : TBase(memInfo)
  94. , Lists(std::move(lists))
  95. {
  96. MKQL_MEM_TAKE(memInfo, Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
  97. Y_ASSERT(!Lists.empty());
  98. }
  99. TExtendStreamValue::~TExtendStreamValue() {
  100. MKQL_MEM_RETURN(GetMemInfo(), Lists.data(), Lists.capacity() * sizeof(NUdf::TUnboxedValue));
  101. }
  102. NUdf::EFetchStatus TExtendStreamValue::Fetch(NUdf::TUnboxedValue& value) {
  103. for (; Index < Lists.size(); ++Index) {
  104. const auto status = Lists[Index].Fetch(value);
  105. if (status != NUdf::EFetchStatus::Finish) {
  106. return status;
  107. }
  108. }
  109. return NUdf::EFetchStatus::Finish;
  110. }
  111. }
  112. }