#pragma once #include "mkql_match_recognize_list.h" #include #include namespace NKikimr::NMiniKQL::NMatchRecognize { template using TMatchedVar = std::vector>; template void Extend(TMatchedVar& var, const R& r) { if (var.empty()) { var.emplace_back(r); } else { MKQL_ENSURE(r.From() > var.back().To(), "Internal logic error"); if (var.back().To() + 1 == r.From() && var.back().NfaIndex() == r.NfaIndex()) { var.back().Extend(); } else { var.emplace_back(r); } } } template using TMatchedVars = std::vector, TMKQLAllocator>>; template NUdf::TUnboxedValue ToValue(const THolderFactory& holderFactory, const R& range) { std::array array = {NUdf::TUnboxedValuePod{range.From()}, NUdf::TUnboxedValuePod{range.To()}}; return holderFactory.RangeAsArray(cbegin(array), cend(array)); } template NUdf::TUnboxedValue ToValue(const THolderFactory& holderFactory, const TMatchedVar& var) { TUnboxedValueVector data; data.reserve(var.size()); for (const auto& r: var) { data.push_back(ToValue(holderFactory, r)); } return holderFactory.VectorAsVectorHolder(std::move(data)); } template inline NUdf::TUnboxedValue ToValue(const THolderFactory& holderFactory, const TMatchedVars& vars) { NUdf::TUnboxedValue* ptr; auto result = holderFactory.CreateDirectArrayHolder(vars.size(), ptr); for (const auto& v: vars) { *ptr++ = ToValue(holderFactory, v); } return result; } ///Optimized reference based implementation to be used as an argument ///for lambdas which produce strict result(do not require lazy access to its arguments) template class TMatchedVarsValue : public TComputationValue> { class TRangeList: public TComputationValue { class TIterator : public TComputationValue { public: TIterator(TMemoryUsageInfo* memInfo, const THolderFactory& holderFactory, const std::vector>& ranges) : TComputationValue(memInfo) , HolderFactory(holderFactory) , Ranges(ranges) , Index(0) {} private: bool Next(NUdf::TUnboxedValue& value) override { if (Ranges.size() == Index){ return false; } value = ToValue(HolderFactory, Ranges[Index++]); return true; } const THolderFactory& HolderFactory; const std::vector>& Ranges; size_t Index; }; public: TRangeList(TMemoryUsageInfo* memInfo, const THolderFactory& holderFactory, const TMatchedVar& v) : TComputationValue(memInfo) , HolderFactory(holderFactory) , Var(v) { } bool HasFastListLength() const override { return true; } ui64 GetListLength() const override { return Var.size(); } bool HasListItems() const override { return !Var.empty(); } NUdf::TUnboxedValue GetListIterator() const override { return HolderFactory.Create(HolderFactory, Var); } private: const THolderFactory& HolderFactory; const TMatchedVar& Var; }; public: TMatchedVarsValue(TMemoryUsageInfo* memInfo, const THolderFactory& holderFactory, const std::vector, TMKQLAllocator>>& vars) : TComputationValue(memInfo) , HolderFactory(holderFactory) , Vars(vars) {} NUdf::TUnboxedValue GetElement(ui32 index) const override { return HolderFactory.Create(HolderFactory, Vars[index]); } private: const THolderFactory& HolderFactory; const std::vector, TMKQLAllocator>>& Vars; }; }//namespace NKikimr::NMiniKQL::NMatchRecognize