mkql_match_recognize_matched_vars.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #pragma once
  2. #include "mkql_match_recognize_list.h"
  3. #include <yql/essentials/minikql/computation/mkql_computation_node_impl.h>
  4. #include <yql/essentials/minikql/computation/mkql_computation_node_holders.h>
  5. namespace NKikimr::NMiniKQL::NMatchRecognize {
  6. template<class R>
  7. using TMatchedVar = std::vector<R, TMKQLAllocator<R>>;
  8. template<class R>
  9. void Extend(TMatchedVar<R>& var, const R& r) {
  10. if (var.empty()) {
  11. var.emplace_back(r);
  12. } else {
  13. MKQL_ENSURE(r.From() > var.back().To(), "Internal logic error");
  14. if (var.back().To() + 1 == r.From() && var.back().NfaIndex() == r.NfaIndex()) {
  15. var.back().Extend();
  16. } else {
  17. var.emplace_back(r);
  18. }
  19. }
  20. }
  21. template<class R>
  22. using TMatchedVars = std::vector<TMatchedVar<R>, TMKQLAllocator<TMatchedVar<R>>>;
  23. template<class R>
  24. NUdf::TUnboxedValue ToValue(const THolderFactory& holderFactory, const R& range) {
  25. std::array<NUdf::TUnboxedValue, 2> array = {NUdf::TUnboxedValuePod{range.From()}, NUdf::TUnboxedValuePod{range.To()}};
  26. return holderFactory.RangeAsArray(cbegin(array), cend(array));
  27. }
  28. template<class R>
  29. NUdf::TUnboxedValue ToValue(const THolderFactory& holderFactory, const TMatchedVar<R>& var) {
  30. TUnboxedValueVector data;
  31. data.reserve(var.size());
  32. for (const auto& r: var) {
  33. data.push_back(ToValue(holderFactory, r));
  34. }
  35. return holderFactory.VectorAsVectorHolder(std::move(data));
  36. }
  37. template<class R>
  38. inline NUdf::TUnboxedValue ToValue(const THolderFactory& holderFactory, const TMatchedVars<R>& vars) {
  39. NUdf::TUnboxedValue* ptr;
  40. auto result = holderFactory.CreateDirectArrayHolder(vars.size(), ptr);
  41. for (const auto& v: vars) {
  42. *ptr++ = ToValue(holderFactory, v);
  43. }
  44. return result;
  45. }
  46. ///Optimized reference based implementation to be used as an argument
  47. ///for lambdas which produce strict result(do not require lazy access to its arguments)
  48. template<class R>
  49. class TMatchedVarsValue : public TComputationValue<TMatchedVarsValue<R>> {
  50. class TRangeList: public TComputationValue<TRangeList> {
  51. class TIterator : public TComputationValue<TIterator> {
  52. public:
  53. TIterator(TMemoryUsageInfo* memInfo, const THolderFactory& holderFactory, const std::vector<R, TMKQLAllocator<R>>& ranges)
  54. : TComputationValue<TIterator>(memInfo)
  55. , HolderFactory(holderFactory)
  56. , Ranges(ranges)
  57. , Index(0)
  58. {}
  59. private:
  60. bool Next(NUdf::TUnboxedValue& value) override {
  61. if (Ranges.size() == Index){
  62. return false;
  63. }
  64. value = ToValue(HolderFactory, Ranges[Index++]);
  65. return true;
  66. }
  67. const THolderFactory& HolderFactory;
  68. const std::vector<R, TMKQLAllocator<R>>& Ranges;
  69. size_t Index;
  70. };
  71. public:
  72. TRangeList(TMemoryUsageInfo* memInfo, const THolderFactory& holderFactory, const TMatchedVar<R>& v)
  73. : TComputationValue<TRangeList>(memInfo)
  74. , HolderFactory(holderFactory)
  75. , Var(v)
  76. {
  77. }
  78. bool HasFastListLength() const override {
  79. return true;
  80. }
  81. ui64 GetListLength() const override {
  82. return Var.size();
  83. }
  84. bool HasListItems() const override {
  85. return !Var.empty();
  86. }
  87. NUdf::TUnboxedValue GetListIterator() const override {
  88. return HolderFactory.Create<TIterator>(HolderFactory, Var);
  89. }
  90. private:
  91. const THolderFactory& HolderFactory;
  92. const TMatchedVar<R>& Var;
  93. };
  94. public:
  95. TMatchedVarsValue(TMemoryUsageInfo* memInfo, const THolderFactory& holderFactory, const std::vector<TMatchedVar<R>, TMKQLAllocator<TMatchedVar<R>>>& vars)
  96. : TComputationValue<TMatchedVarsValue>(memInfo)
  97. , HolderFactory(holderFactory)
  98. , Vars(vars)
  99. {}
  100. NUdf::TUnboxedValue GetElement(ui32 index) const override {
  101. return HolderFactory.Create<TRangeList>(HolderFactory, Vars[index]);
  102. }
  103. private:
  104. const THolderFactory& HolderFactory;
  105. const std::vector<TMatchedVar<R>, TMKQLAllocator<TMatchedVar<R>>>& Vars;
  106. };
  107. }//namespace NKikimr::NMiniKQL::NMatchRecognize