be/src/exprs/aggregate/aggregate_function_sequence_match.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | // This file is copied from |
19 | | // https://github.com/ClickHouse/ClickHouse/blob/master/AggregateFunctionSequenceMatch.h |
20 | | // and modified by Doris |
21 | | |
22 | | #pragma once |
23 | | |
24 | | #include <string.h> |
25 | | |
26 | | #include <algorithm> |
27 | | #include <bitset> |
28 | | #include <boost/iterator/iterator_facade.hpp> |
29 | | #include <cstdint> |
30 | | #include <functional> |
31 | | #include <iterator> |
32 | | #include <memory> |
33 | | #include <stack> |
34 | | #include <string> |
35 | | #include <tuple> |
36 | | #include <utility> |
37 | | #include <vector> |
38 | | |
39 | | #include "common/logging.h" |
40 | | #include "core/assert_cast.h" |
41 | | #include "core/column/column_string.h" |
42 | | #include "core/column/column_vector.h" |
43 | | #include "core/data_type/data_type_number.h" |
44 | | #include "core/pod_array_fwd.h" |
45 | | #include "core/string_ref.h" |
46 | | #include "core/types.h" |
47 | | #include "exprs/aggregate/aggregate_function.h" |
48 | | #include "util/io_helper.h" |
49 | | |
50 | | namespace doris { |
51 | | #include "common/compile_check_begin.h" |
52 | | class Arena; |
53 | | class BufferReadable; |
54 | | class BufferWritable; |
55 | | class IColumn; |
56 | | } // namespace doris |
57 | | |
58 | | namespace doris { |
59 | | |
60 | | template <template <typename> class Comparator> |
61 | | struct ComparePairFirst final { |
62 | | template <typename T1, typename T2> |
63 | 30 | bool operator()(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs) const { |
64 | 30 | return Comparator<T1> {}(lhs.first, rhs.first); |
65 | 30 | } _ZNK5doris16ComparePairFirstISt4lessEclINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEEEbRKSt4pairIT_T0_ESE_ Line | Count | Source | 63 | 30 | bool operator()(const std::pair<T1, T2>& lhs, const std::pair<T1, T2>& rhs) const { | 64 | 30 | return Comparator<T1> {}(lhs.first, rhs.first); | 65 | 30 | } |
Unexecuted instantiation: _ZNK5doris16ComparePairFirstISt4lessEclINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEEEbRKSt4pairIT_T0_ESE_ |
66 | | }; |
67 | | |
68 | | static constexpr size_t MAX_EVENTS = 32; |
69 | | |
70 | | /// Max number of iterations to match the pattern against a sequence, exception thrown when exceeded |
71 | | constexpr auto sequence_match_max_iterations = 1000000l; |
72 | | |
73 | | template <PrimitiveType T, typename Derived> |
74 | | struct AggregateFunctionSequenceMatchData final { |
75 | | using Timestamp = typename PrimitiveTypeTraits<T>::CppType; |
76 | | using NativeType = |
77 | | std::conditional_t<T == TYPE_DATEV2, uint32_t, |
78 | | std::conditional_t<T == TYPE_DATETIMEV2, uint64_t, |
79 | | typename PrimitiveTypeTraits<T>::CppType>>; |
80 | | using Events = std::bitset<MAX_EVENTS>; |
81 | | using TimestampEvents = std::pair<Timestamp, Events>; |
82 | | using Comparator = ComparePairFirst<std::less>; |
83 | | |
84 | 14 | AggregateFunctionSequenceMatchData() { reset(); }_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEEC2Ev Line | Count | Source | 84 | 7 | AggregateFunctionSequenceMatchData() { reset(); } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEEC2Ev _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEEC2Ev Line | Count | Source | 84 | 7 | AggregateFunctionSequenceMatchData() { reset(); } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEEC2Ev |
85 | | |
86 | | public: |
87 | 10 | const std::string get_pattern() const { return pattern; }_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE11get_patternB5cxx11Ev Line | Count | Source | 87 | 5 | const std::string get_pattern() const { return pattern; } |
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE11get_patternB5cxx11Ev _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE11get_patternB5cxx11Ev Line | Count | Source | 87 | 5 | const std::string get_pattern() const { return pattern; } |
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE11get_patternB5cxx11Ev |
88 | | |
89 | 10 | size_t get_arg_count() const { return arg_count; }_ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13get_arg_countEv Line | Count | Source | 89 | 5 | size_t get_arg_count() const { return arg_count; } |
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13get_arg_countEv _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13get_arg_countEv Line | Count | Source | 89 | 5 | size_t get_arg_count() const { return arg_count; } |
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13get_arg_countEv |
90 | | |
91 | 26 | void init(const std::string pattern_, size_t arg_count_) { |
92 | 26 | if (!init_flag) { |
93 | 12 | this->pattern = pattern_; |
94 | 12 | this->arg_count = arg_count_; |
95 | 12 | parse_pattern(); |
96 | 12 | init_flag = true; |
97 | 12 | } |
98 | 26 | } _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE4initENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm Line | Count | Source | 91 | 13 | void init(const std::string pattern_, size_t arg_count_) { | 92 | 13 | if (!init_flag) { | 93 | 6 | this->pattern = pattern_; | 94 | 6 | this->arg_count = arg_count_; | 95 | 6 | parse_pattern(); | 96 | 6 | init_flag = true; | 97 | 6 | } | 98 | 13 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE4initENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE4initENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm Line | Count | Source | 91 | 13 | void init(const std::string pattern_, size_t arg_count_) { | 92 | 13 | if (!init_flag) { | 93 | 6 | this->pattern = pattern_; | 94 | 6 | this->arg_count = arg_count_; | 95 | 6 | parse_pattern(); | 96 | 6 | init_flag = true; | 97 | 6 | } | 98 | 13 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE4initENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm |
99 | | |
100 | 14 | void reset() { |
101 | 14 | sorted = true; |
102 | 14 | init_flag = false; |
103 | 14 | pattern_has_time = false; |
104 | 14 | pattern = ""; |
105 | 14 | arg_count = 0; |
106 | 14 | conditions_met.reset(); |
107 | 14 | conditions_in_pattern.reset(); |
108 | | |
109 | 14 | events_list.clear(); |
110 | 14 | actions.clear(); |
111 | 14 | dfa_states.clear(); |
112 | 14 | } _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5resetEv Line | Count | Source | 100 | 7 | void reset() { | 101 | 7 | sorted = true; | 102 | 7 | init_flag = false; | 103 | 7 | pattern_has_time = false; | 104 | 7 | pattern = ""; | 105 | 7 | arg_count = 0; | 106 | 7 | conditions_met.reset(); | 107 | 7 | conditions_in_pattern.reset(); | 108 | | | 109 | 7 | events_list.clear(); | 110 | 7 | actions.clear(); | 111 | 7 | dfa_states.clear(); | 112 | 7 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5resetEv _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5resetEv Line | Count | Source | 100 | 7 | void reset() { | 101 | 7 | sorted = true; | 102 | 7 | init_flag = false; | 103 | 7 | pattern_has_time = false; | 104 | 7 | pattern = ""; | 105 | 7 | arg_count = 0; | 106 | 7 | conditions_met.reset(); | 107 | 7 | conditions_in_pattern.reset(); | 108 | | | 109 | 7 | events_list.clear(); | 110 | 7 | actions.clear(); | 111 | 7 | dfa_states.clear(); | 112 | 7 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5resetEv |
113 | | |
114 | 16 | void add(const Timestamp& timestamp, const Events& events) { |
115 | | /// store information exclusively for rows with at least one event |
116 | 16 | if (events.any()) { |
117 | 13 | events_list.emplace_back(timestamp, events); |
118 | 13 | sorted = false; |
119 | 13 | conditions_met |= events; |
120 | 13 | } |
121 | 16 | } _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE3addERKNS_11DateV2ValueINS_19DateTimeV2ValueTypeEEERKSt6bitsetILm32EE Line | Count | Source | 114 | 8 | void add(const Timestamp& timestamp, const Events& events) { | 115 | | /// store information exclusively for rows with at least one event | 116 | 8 | if (events.any()) { | 117 | 5 | events_list.emplace_back(timestamp, events); | 118 | 5 | sorted = false; | 119 | 5 | conditions_met |= events; | 120 | 5 | } | 121 | 8 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE3addERKNS_11DateV2ValueINS_15DateV2ValueTypeEEERKSt6bitsetILm32EE _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE3addERKNS_11DateV2ValueINS_19DateTimeV2ValueTypeEEERKSt6bitsetILm32EE Line | Count | Source | 114 | 8 | void add(const Timestamp& timestamp, const Events& events) { | 115 | | /// store information exclusively for rows with at least one event | 116 | 8 | if (events.any()) { | 117 | 8 | events_list.emplace_back(timestamp, events); | 118 | 8 | sorted = false; | 119 | 8 | conditions_met |= events; | 120 | 8 | } | 121 | 8 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE3addERKNS_11DateV2ValueINS_15DateV2ValueTypeEEERKSt6bitsetILm32EE |
122 | | |
123 | 4 | void merge(const AggregateFunctionSequenceMatchData& other) { |
124 | 4 | if (other.events_list.empty()) return; |
125 | | |
126 | 2 | events_list.insert(std::end(events_list), std::begin(other.events_list), |
127 | 2 | std::end(other.events_list)); |
128 | 2 | sorted = false; |
129 | 2 | conditions_met |= other.conditions_met; |
130 | 2 | } _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5mergeERKS4_ Line | Count | Source | 123 | 2 | void merge(const AggregateFunctionSequenceMatchData& other) { | 124 | 2 | if (other.events_list.empty()) return; | 125 | | | 126 | 1 | events_list.insert(std::end(events_list), std::begin(other.events_list), | 127 | 1 | std::end(other.events_list)); | 128 | 1 | sorted = false; | 129 | 1 | conditions_met |= other.conditions_met; | 130 | 1 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5mergeERKS4_ _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5mergeERKS4_ Line | Count | Source | 123 | 2 | void merge(const AggregateFunctionSequenceMatchData& other) { | 124 | 2 | if (other.events_list.empty()) return; | 125 | | | 126 | 1 | events_list.insert(std::end(events_list), std::begin(other.events_list), | 127 | 1 | std::end(other.events_list)); | 128 | 1 | sorted = false; | 129 | 1 | conditions_met |= other.conditions_met; | 130 | 1 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5mergeERKS4_ |
131 | | |
132 | | // todo: rethink the sort method. |
133 | 7 | void sort() { |
134 | 7 | if (sorted) return; |
135 | | |
136 | 7 | std::sort(std::begin(events_list), std::end(events_list), Comparator {}); |
137 | 7 | sorted = true; |
138 | 7 | } _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE4sortEv Line | Count | Source | 133 | 3 | void sort() { | 134 | 3 | if (sorted) return; | 135 | | | 136 | 3 | std::sort(std::begin(events_list), std::end(events_list), Comparator {}); | 137 | 3 | sorted = true; | 138 | 3 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE4sortEv _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE4sortEv Line | Count | Source | 133 | 4 | void sort() { | 134 | 4 | if (sorted) return; | 135 | | | 136 | 4 | std::sort(std::begin(events_list), std::end(events_list), Comparator {}); | 137 | 4 | sorted = true; | 138 | 4 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE4sortEv |
139 | | |
140 | 6 | void write(BufferWritable& buf) const { |
141 | 6 | buf.write_binary(sorted); |
142 | 6 | buf.write_binary(events_list.size()); |
143 | | |
144 | 10 | for (const auto& events : events_list) { |
145 | 10 | buf.write_binary(events.first); |
146 | 10 | buf.write_binary(events.second.to_ulong()); |
147 | 10 | } |
148 | | |
149 | | // This is std::bitset<32>, which will not exceed 32 bits. |
150 | 6 | UInt32 conditions_met_value = (UInt32)conditions_met.to_ulong(); |
151 | 6 | buf.write_binary(conditions_met_value); |
152 | | |
153 | 6 | buf.write_binary(pattern); |
154 | 6 | buf.write_binary(arg_count); |
155 | 6 | } _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5writeERNS_14BufferWritableE Line | Count | Source | 140 | 3 | void write(BufferWritable& buf) const { | 141 | 3 | buf.write_binary(sorted); | 142 | 3 | buf.write_binary(events_list.size()); | 143 | | | 144 | 4 | for (const auto& events : events_list) { | 145 | 4 | buf.write_binary(events.first); | 146 | 4 | buf.write_binary(events.second.to_ulong()); | 147 | 4 | } | 148 | | | 149 | | // This is std::bitset<32>, which will not exceed 32 bits. | 150 | 3 | UInt32 conditions_met_value = (UInt32)conditions_met.to_ulong(); | 151 | 3 | buf.write_binary(conditions_met_value); | 152 | | | 153 | 3 | buf.write_binary(pattern); | 154 | 3 | buf.write_binary(arg_count); | 155 | 3 | } |
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5writeERNS_14BufferWritableE _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5writeERNS_14BufferWritableE Line | Count | Source | 140 | 3 | void write(BufferWritable& buf) const { | 141 | 3 | buf.write_binary(sorted); | 142 | 3 | buf.write_binary(events_list.size()); | 143 | | | 144 | 6 | for (const auto& events : events_list) { | 145 | 6 | buf.write_binary(events.first); | 146 | 6 | buf.write_binary(events.second.to_ulong()); | 147 | 6 | } | 148 | | | 149 | | // This is std::bitset<32>, which will not exceed 32 bits. | 150 | 3 | UInt32 conditions_met_value = (UInt32)conditions_met.to_ulong(); | 151 | 3 | buf.write_binary(conditions_met_value); | 152 | | | 153 | 3 | buf.write_binary(pattern); | 154 | 3 | buf.write_binary(arg_count); | 155 | 3 | } |
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5writeERNS_14BufferWritableE |
156 | | |
157 | 6 | void read(BufferReadable& buf) { |
158 | 6 | buf.read_binary(sorted); |
159 | | |
160 | 6 | size_t events_list_size; |
161 | 6 | buf.read_binary(events_list_size); |
162 | | |
163 | 6 | events_list.clear(); |
164 | 6 | events_list.reserve(events_list_size); |
165 | | |
166 | 16 | for (size_t i = 0; i < events_list_size; ++i) { |
167 | 10 | Timestamp timestamp; |
168 | 10 | buf.read_binary(timestamp); |
169 | | |
170 | 10 | UInt64 events; |
171 | 10 | buf.read_binary(events); |
172 | | |
173 | 10 | events_list.emplace_back(timestamp, Events {events}); |
174 | 10 | } |
175 | | |
176 | 6 | UInt32 conditions_met_value; |
177 | 6 | buf.read_binary(conditions_met_value); |
178 | 6 | conditions_met = conditions_met_value; |
179 | | |
180 | 6 | buf.read_binary(pattern); |
181 | 6 | buf.read_binary(arg_count); |
182 | 6 | } _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE4readERNS_14BufferReadableE Line | Count | Source | 157 | 3 | void read(BufferReadable& buf) { | 158 | 3 | buf.read_binary(sorted); | 159 | | | 160 | 3 | size_t events_list_size; | 161 | 3 | buf.read_binary(events_list_size); | 162 | | | 163 | 3 | events_list.clear(); | 164 | 3 | events_list.reserve(events_list_size); | 165 | | | 166 | 7 | for (size_t i = 0; i < events_list_size; ++i) { | 167 | 4 | Timestamp timestamp; | 168 | 4 | buf.read_binary(timestamp); | 169 | | | 170 | 4 | UInt64 events; | 171 | 4 | buf.read_binary(events); | 172 | | | 173 | 4 | events_list.emplace_back(timestamp, Events {events}); | 174 | 4 | } | 175 | | | 176 | 3 | UInt32 conditions_met_value; | 177 | 3 | buf.read_binary(conditions_met_value); | 178 | 3 | conditions_met = conditions_met_value; | 179 | | | 180 | 3 | buf.read_binary(pattern); | 181 | 3 | buf.read_binary(arg_count); | 182 | 3 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE4readERNS_14BufferReadableE _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE4readERNS_14BufferReadableE Line | Count | Source | 157 | 3 | void read(BufferReadable& buf) { | 158 | 3 | buf.read_binary(sorted); | 159 | | | 160 | 3 | size_t events_list_size; | 161 | 3 | buf.read_binary(events_list_size); | 162 | | | 163 | 3 | events_list.clear(); | 164 | 3 | events_list.reserve(events_list_size); | 165 | | | 166 | 9 | for (size_t i = 0; i < events_list_size; ++i) { | 167 | 6 | Timestamp timestamp; | 168 | 6 | buf.read_binary(timestamp); | 169 | | | 170 | 6 | UInt64 events; | 171 | 6 | buf.read_binary(events); | 172 | | | 173 | 6 | events_list.emplace_back(timestamp, Events {events}); | 174 | 6 | } | 175 | | | 176 | 3 | UInt32 conditions_met_value; | 177 | 3 | buf.read_binary(conditions_met_value); | 178 | 3 | conditions_met = conditions_met_value; | 179 | | | 180 | 3 | buf.read_binary(pattern); | 181 | 3 | buf.read_binary(arg_count); | 182 | 3 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE4readERNS_14BufferReadableE |
183 | | |
184 | | private: |
185 | | enum class PatternActionType { |
186 | | SpecificEvent, |
187 | | AnyEvent, |
188 | | KleeneStar, |
189 | | TimeLessOrEqual, |
190 | | TimeLess, |
191 | | TimeGreaterOrEqual, |
192 | | TimeGreater, |
193 | | TimeEqual |
194 | | }; |
195 | | |
196 | | struct PatternAction final { |
197 | | PatternActionType type; |
198 | | std::uint64_t extra; |
199 | | |
200 | | PatternAction() = default; |
201 | | explicit PatternAction(const PatternActionType type_, const std::uint64_t extra_ = 0) |
202 | 32 | : type {type_}, extra {extra_} {}_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13PatternActionC2ENS4_17PatternActionTypeEm Line | Count | Source | 202 | 16 | : type {type_}, extra {extra_} {} |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13PatternActionC2ENS4_17PatternActionTypeEm _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13PatternActionC2ENS4_17PatternActionTypeEm Line | Count | Source | 202 | 16 | : type {type_}, extra {extra_} {} |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13PatternActionC2ENS4_17PatternActionTypeEm |
203 | | }; |
204 | | |
205 | | using PatternActions = PODArrayWithStackMemory<PatternAction, 64>; |
206 | | |
207 | | Derived& derived() { return assert_cast<Derived&, TypeCheckOnRelease::DISABLE>(*this); } |
208 | | |
209 | 12 | void parse_pattern() { |
210 | 12 | actions.clear(); |
211 | 12 | actions.emplace_back(PatternActionType::KleeneStar); |
212 | | |
213 | 12 | dfa_states.clear(); |
214 | 12 | dfa_states.emplace_back(true); |
215 | | |
216 | 12 | pattern_has_time = false; |
217 | | |
218 | 12 | const char* pos = pattern.data(); |
219 | 12 | const char* begin = pos; |
220 | 12 | const char* end = pos + pattern.size(); |
221 | | |
222 | | // Pattern is checked in fe, so pattern should be valid here, we check it and if pattern is invalid, we return. |
223 | 12 | auto throw_exception = [&](const std::string& msg) { |
224 | 0 | LOG(WARNING) << msg + " '" + std::string(pos, end) + "' at position " + |
225 | 0 | std::to_string(pos - begin); |
226 | 0 | }; Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13parse_patternEvENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE_clESC_ Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13parse_patternEvENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE_clESC_ Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13parse_patternEvENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE_clESC_ Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13parse_patternEvENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE_clESC_ |
227 | | |
228 | 60 | auto match = [&pos, end](const char* str) mutable { |
229 | 60 | size_t length = strlen(str); |
230 | 60 | if (pos + length <= end && 0 == memcmp(pos, str, length)) { |
231 | 40 | pos += length; |
232 | 40 | return true; |
233 | 40 | } |
234 | 20 | return false; |
235 | 60 | }; _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13parse_patternEvENUlPKcE_clES6_ Line | Count | Source | 228 | 30 | auto match = [&pos, end](const char* str) mutable { | 229 | 30 | size_t length = strlen(str); | 230 | 30 | if (pos + length <= end && 0 == memcmp(pos, str, length)) { | 231 | 20 | pos += length; | 232 | 20 | return true; | 233 | 20 | } | 234 | 10 | return false; | 235 | 30 | }; |
Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13parse_patternEvENUlPKcE_clES6_ _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13parse_patternEvENUlPKcE_clES6_ Line | Count | Source | 228 | 30 | auto match = [&pos, end](const char* str) mutable { | 229 | 30 | size_t length = strlen(str); | 230 | 30 | if (pos + length <= end && 0 == memcmp(pos, str, length)) { | 231 | 20 | pos += length; | 232 | 20 | return true; | 233 | 20 | } | 234 | 10 | return false; | 235 | 30 | }; |
Unexecuted instantiation: _ZZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13parse_patternEvENUlPKcE_clES6_ |
236 | | |
237 | 32 | while (pos < end) { |
238 | 20 | if (match("(?")) { |
239 | 20 | if (match("t")) { |
240 | 0 | PatternActionType type; |
241 | |
|
242 | 0 | if (match("<=")) |
243 | 0 | type = PatternActionType::TimeLessOrEqual; |
244 | 0 | else if (match("<")) |
245 | 0 | type = PatternActionType::TimeLess; |
246 | 0 | else if (match(">=")) |
247 | 0 | type = PatternActionType::TimeGreaterOrEqual; |
248 | 0 | else if (match(">")) |
249 | 0 | type = PatternActionType::TimeGreater; |
250 | 0 | else if (match("==")) |
251 | 0 | type = PatternActionType::TimeEqual; |
252 | 0 | else { |
253 | 0 | throw_exception("Unknown time condition"); |
254 | 0 | return; |
255 | 0 | } |
256 | | |
257 | 0 | NativeType duration = 0; |
258 | 0 | const auto* prev_pos = pos; |
259 | 0 | pos = try_read_first_int_text(duration, pos, end); |
260 | 0 | if (pos == prev_pos) { |
261 | 0 | throw_exception("Could not parse number"); |
262 | 0 | return; |
263 | 0 | } |
264 | | |
265 | 0 | if (actions.back().type != PatternActionType::SpecificEvent && |
266 | 0 | actions.back().type != PatternActionType::AnyEvent && |
267 | 0 | actions.back().type != PatternActionType::KleeneStar) { |
268 | 0 | throw_exception( |
269 | 0 | "Temporal condition should be preceded by an event condition"); |
270 | 0 | return; |
271 | 0 | } |
272 | | |
273 | 0 | pattern_has_time = true; |
274 | 0 | actions.emplace_back(type, duration); |
275 | 20 | } else { |
276 | 20 | UInt64 event_number = 0; |
277 | 20 | const auto* prev_pos = pos; |
278 | 20 | pos = try_read_first_int_text(event_number, pos, end); |
279 | 20 | if (pos == prev_pos) throw_exception("Could not parse number"); |
280 | | |
281 | 20 | if (event_number > arg_count - 1) { |
282 | 0 | throw_exception("Event number " + std::to_string(event_number) + |
283 | 0 | " is out of range"); |
284 | 0 | return; |
285 | 0 | } |
286 | | |
287 | 20 | actions.emplace_back(PatternActionType::SpecificEvent, event_number - 1); |
288 | 20 | dfa_states.back().transition = DFATransition::SpecificEvent; |
289 | 20 | dfa_states.back().event = static_cast<uint32_t>(event_number - 1); |
290 | 20 | dfa_states.emplace_back(); |
291 | 20 | conditions_in_pattern.set(event_number - 1); |
292 | 20 | } |
293 | | |
294 | 20 | if (!match(")")) { |
295 | 0 | throw_exception("Expected closing parenthesis, found"); |
296 | 0 | return; |
297 | 0 | } |
298 | | |
299 | 20 | } else if (match(".*")) { |
300 | 0 | actions.emplace_back(PatternActionType::KleeneStar); |
301 | 0 | dfa_states.back().has_kleene = true; |
302 | 0 | } else if (match(".")) { |
303 | 0 | actions.emplace_back(PatternActionType::AnyEvent); |
304 | 0 | dfa_states.back().transition = DFATransition::AnyEvent; |
305 | 0 | dfa_states.emplace_back(); |
306 | 0 | } else { |
307 | 0 | throw_exception("Could not parse pattern, unexpected starting symbol"); |
308 | 0 | return; |
309 | 0 | } |
310 | 20 | } |
311 | 12 | } _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE13parse_patternEv Line | Count | Source | 209 | 6 | void parse_pattern() { | 210 | 6 | actions.clear(); | 211 | 6 | actions.emplace_back(PatternActionType::KleeneStar); | 212 | | | 213 | 6 | dfa_states.clear(); | 214 | 6 | dfa_states.emplace_back(true); | 215 | | | 216 | 6 | pattern_has_time = false; | 217 | | | 218 | 6 | const char* pos = pattern.data(); | 219 | 6 | const char* begin = pos; | 220 | 6 | const char* end = pos + pattern.size(); | 221 | | | 222 | | // Pattern is checked in fe, so pattern should be valid here, we check it and if pattern is invalid, we return. | 223 | 6 | auto throw_exception = [&](const std::string& msg) { | 224 | 6 | LOG(WARNING) << msg + " '" + std::string(pos, end) + "' at position " + | 225 | 6 | std::to_string(pos - begin); | 226 | 6 | }; | 227 | | | 228 | 6 | auto match = [&pos, end](const char* str) mutable { | 229 | 6 | size_t length = strlen(str); | 230 | 6 | if (pos + length <= end && 0 == memcmp(pos, str, length)) { | 231 | 6 | pos += length; | 232 | 6 | return true; | 233 | 6 | } | 234 | 6 | return false; | 235 | 6 | }; | 236 | | | 237 | 16 | while (pos < end) { | 238 | 10 | if (match("(?")) { | 239 | 10 | if (match("t")) { | 240 | 0 | PatternActionType type; | 241 | |
| 242 | 0 | if (match("<=")) | 243 | 0 | type = PatternActionType::TimeLessOrEqual; | 244 | 0 | else if (match("<")) | 245 | 0 | type = PatternActionType::TimeLess; | 246 | 0 | else if (match(">=")) | 247 | 0 | type = PatternActionType::TimeGreaterOrEqual; | 248 | 0 | else if (match(">")) | 249 | 0 | type = PatternActionType::TimeGreater; | 250 | 0 | else if (match("==")) | 251 | 0 | type = PatternActionType::TimeEqual; | 252 | 0 | else { | 253 | 0 | throw_exception("Unknown time condition"); | 254 | 0 | return; | 255 | 0 | } | 256 | | | 257 | 0 | NativeType duration = 0; | 258 | 0 | const auto* prev_pos = pos; | 259 | 0 | pos = try_read_first_int_text(duration, pos, end); | 260 | 0 | if (pos == prev_pos) { | 261 | 0 | throw_exception("Could not parse number"); | 262 | 0 | return; | 263 | 0 | } | 264 | | | 265 | 0 | if (actions.back().type != PatternActionType::SpecificEvent && | 266 | 0 | actions.back().type != PatternActionType::AnyEvent && | 267 | 0 | actions.back().type != PatternActionType::KleeneStar) { | 268 | 0 | throw_exception( | 269 | 0 | "Temporal condition should be preceded by an event condition"); | 270 | 0 | return; | 271 | 0 | } | 272 | | | 273 | 0 | pattern_has_time = true; | 274 | 0 | actions.emplace_back(type, duration); | 275 | 10 | } else { | 276 | 10 | UInt64 event_number = 0; | 277 | 10 | const auto* prev_pos = pos; | 278 | 10 | pos = try_read_first_int_text(event_number, pos, end); | 279 | 10 | if (pos == prev_pos) throw_exception("Could not parse number"); | 280 | | | 281 | 10 | if (event_number > arg_count - 1) { | 282 | 0 | throw_exception("Event number " + std::to_string(event_number) + | 283 | 0 | " is out of range"); | 284 | 0 | return; | 285 | 0 | } | 286 | | | 287 | 10 | actions.emplace_back(PatternActionType::SpecificEvent, event_number - 1); | 288 | 10 | dfa_states.back().transition = DFATransition::SpecificEvent; | 289 | 10 | dfa_states.back().event = static_cast<uint32_t>(event_number - 1); | 290 | 10 | dfa_states.emplace_back(); | 291 | 10 | conditions_in_pattern.set(event_number - 1); | 292 | 10 | } | 293 | | | 294 | 10 | if (!match(")")) { | 295 | 0 | throw_exception("Expected closing parenthesis, found"); | 296 | 0 | return; | 297 | 0 | } | 298 | | | 299 | 10 | } else if (match(".*")) { | 300 | 0 | actions.emplace_back(PatternActionType::KleeneStar); | 301 | 0 | dfa_states.back().has_kleene = true; | 302 | 0 | } else if (match(".")) { | 303 | 0 | actions.emplace_back(PatternActionType::AnyEvent); | 304 | 0 | dfa_states.back().transition = DFATransition::AnyEvent; | 305 | 0 | dfa_states.emplace_back(); | 306 | 0 | } else { | 307 | 0 | throw_exception("Could not parse pattern, unexpected starting symbol"); | 308 | 0 | return; | 309 | 0 | } | 310 | 10 | } | 311 | 6 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE13parse_patternEv _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE13parse_patternEv Line | Count | Source | 209 | 6 | void parse_pattern() { | 210 | 6 | actions.clear(); | 211 | 6 | actions.emplace_back(PatternActionType::KleeneStar); | 212 | | | 213 | 6 | dfa_states.clear(); | 214 | 6 | dfa_states.emplace_back(true); | 215 | | | 216 | 6 | pattern_has_time = false; | 217 | | | 218 | 6 | const char* pos = pattern.data(); | 219 | 6 | const char* begin = pos; | 220 | 6 | const char* end = pos + pattern.size(); | 221 | | | 222 | | // Pattern is checked in fe, so pattern should be valid here, we check it and if pattern is invalid, we return. | 223 | 6 | auto throw_exception = [&](const std::string& msg) { | 224 | 6 | LOG(WARNING) << msg + " '" + std::string(pos, end) + "' at position " + | 225 | 6 | std::to_string(pos - begin); | 226 | 6 | }; | 227 | | | 228 | 6 | auto match = [&pos, end](const char* str) mutable { | 229 | 6 | size_t length = strlen(str); | 230 | 6 | if (pos + length <= end && 0 == memcmp(pos, str, length)) { | 231 | 6 | pos += length; | 232 | 6 | return true; | 233 | 6 | } | 234 | 6 | return false; | 235 | 6 | }; | 236 | | | 237 | 16 | while (pos < end) { | 238 | 10 | if (match("(?")) { | 239 | 10 | if (match("t")) { | 240 | 0 | PatternActionType type; | 241 | |
| 242 | 0 | if (match("<=")) | 243 | 0 | type = PatternActionType::TimeLessOrEqual; | 244 | 0 | else if (match("<")) | 245 | 0 | type = PatternActionType::TimeLess; | 246 | 0 | else if (match(">=")) | 247 | 0 | type = PatternActionType::TimeGreaterOrEqual; | 248 | 0 | else if (match(">")) | 249 | 0 | type = PatternActionType::TimeGreater; | 250 | 0 | else if (match("==")) | 251 | 0 | type = PatternActionType::TimeEqual; | 252 | 0 | else { | 253 | 0 | throw_exception("Unknown time condition"); | 254 | 0 | return; | 255 | 0 | } | 256 | | | 257 | 0 | NativeType duration = 0; | 258 | 0 | const auto* prev_pos = pos; | 259 | 0 | pos = try_read_first_int_text(duration, pos, end); | 260 | 0 | if (pos == prev_pos) { | 261 | 0 | throw_exception("Could not parse number"); | 262 | 0 | return; | 263 | 0 | } | 264 | | | 265 | 0 | if (actions.back().type != PatternActionType::SpecificEvent && | 266 | 0 | actions.back().type != PatternActionType::AnyEvent && | 267 | 0 | actions.back().type != PatternActionType::KleeneStar) { | 268 | 0 | throw_exception( | 269 | 0 | "Temporal condition should be preceded by an event condition"); | 270 | 0 | return; | 271 | 0 | } | 272 | | | 273 | 0 | pattern_has_time = true; | 274 | 0 | actions.emplace_back(type, duration); | 275 | 10 | } else { | 276 | 10 | UInt64 event_number = 0; | 277 | 10 | const auto* prev_pos = pos; | 278 | 10 | pos = try_read_first_int_text(event_number, pos, end); | 279 | 10 | if (pos == prev_pos) throw_exception("Could not parse number"); | 280 | | | 281 | 10 | if (event_number > arg_count - 1) { | 282 | 0 | throw_exception("Event number " + std::to_string(event_number) + | 283 | 0 | " is out of range"); | 284 | 0 | return; | 285 | 0 | } | 286 | | | 287 | 10 | actions.emplace_back(PatternActionType::SpecificEvent, event_number - 1); | 288 | 10 | dfa_states.back().transition = DFATransition::SpecificEvent; | 289 | 10 | dfa_states.back().event = static_cast<uint32_t>(event_number - 1); | 290 | 10 | dfa_states.emplace_back(); | 291 | 10 | conditions_in_pattern.set(event_number - 1); | 292 | 10 | } | 293 | | | 294 | 10 | if (!match(")")) { | 295 | 0 | throw_exception("Expected closing parenthesis, found"); | 296 | 0 | return; | 297 | 0 | } | 298 | | | 299 | 10 | } else if (match(".*")) { | 300 | 0 | actions.emplace_back(PatternActionType::KleeneStar); | 301 | 0 | dfa_states.back().has_kleene = true; | 302 | 0 | } else if (match(".")) { | 303 | 0 | actions.emplace_back(PatternActionType::AnyEvent); | 304 | 0 | dfa_states.back().transition = DFATransition::AnyEvent; | 305 | 0 | dfa_states.emplace_back(); | 306 | 0 | } else { | 307 | 0 | throw_exception("Could not parse pattern, unexpected starting symbol"); | 308 | 0 | return; | 309 | 0 | } | 310 | 10 | } | 311 | 6 | } |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE13parse_patternEv |
312 | | |
313 | | public: |
314 | | /// Uses a DFA based approach in order to better handle patterns without |
315 | | /// time assertions. |
316 | | /// |
317 | | /// NOTE: This implementation relies on the assumption that the pattern is *small*. |
318 | | /// |
319 | | /// This algorithm performs in O(mn) (with m the number of DFA states and N the number |
320 | | /// of events) with a memory consumption and memory allocations in O(m). It means that |
321 | | /// if n >>> m (which is expected to be the case), this algorithm can be considered linear. |
322 | | template <typename EventEntry> |
323 | 3 | bool dfa_match(EventEntry& events_it, const EventEntry events_end) const { |
324 | 3 | using ActiveStates = std::vector<bool>; |
325 | | /// Those two vectors keep track of which states should be considered for the current |
326 | | /// event as well as the states which should be considered for the next event. |
327 | 3 | ActiveStates active_states(dfa_states.size(), false); |
328 | 3 | ActiveStates next_active_states(dfa_states.size(), false); |
329 | 3 | active_states[0] = true; |
330 | | |
331 | | /// Keeps track of dead-ends in order not to iterate over all the events to realize that |
332 | | /// the match failed. |
333 | 3 | size_t n_active = 1; |
334 | | |
335 | 9 | for (/* empty */; events_it != events_end && n_active > 0 && !active_states.back(); |
336 | 6 | ++events_it) { |
337 | 6 | n_active = 0; |
338 | 6 | next_active_states.assign(dfa_states.size(), false); |
339 | | |
340 | 24 | for (size_t state = 0; state < dfa_states.size(); ++state) { |
341 | 18 | if (!active_states[state]) { |
342 | 9 | continue; |
343 | 9 | } |
344 | | |
345 | 9 | switch (dfa_states[state].transition) { |
346 | 0 | case DFATransition::None: |
347 | 0 | break; |
348 | 0 | case DFATransition::AnyEvent: |
349 | 0 | next_active_states[state + 1] = true; |
350 | 0 | ++n_active; |
351 | 0 | break; |
352 | 9 | case DFATransition::SpecificEvent: |
353 | 9 | if (events_it->second.test(dfa_states[state].event)) { |
354 | 6 | next_active_states[state + 1] = true; |
355 | 6 | ++n_active; |
356 | 6 | } |
357 | 9 | break; |
358 | 9 | } |
359 | | |
360 | 9 | if (dfa_states[state].has_kleene) { |
361 | 6 | next_active_states[state] = true; |
362 | 6 | ++n_active; |
363 | 6 | } |
364 | 9 | } |
365 | 6 | swap(active_states, next_active_states); |
366 | 6 | } |
367 | | |
368 | 3 | return active_states.back(); |
369 | 3 | } _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE9dfa_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ Line | Count | Source | 323 | 3 | bool dfa_match(EventEntry& events_it, const EventEntry events_end) const { | 324 | 3 | using ActiveStates = std::vector<bool>; | 325 | | /// Those two vectors keep track of which states should be considered for the current | 326 | | /// event as well as the states which should be considered for the next event. | 327 | 3 | ActiveStates active_states(dfa_states.size(), false); | 328 | 3 | ActiveStates next_active_states(dfa_states.size(), false); | 329 | 3 | active_states[0] = true; | 330 | | | 331 | | /// Keeps track of dead-ends in order not to iterate over all the events to realize that | 332 | | /// the match failed. | 333 | 3 | size_t n_active = 1; | 334 | | | 335 | 9 | for (/* empty */; events_it != events_end && n_active > 0 && !active_states.back(); | 336 | 6 | ++events_it) { | 337 | 6 | n_active = 0; | 338 | 6 | next_active_states.assign(dfa_states.size(), false); | 339 | | | 340 | 24 | for (size_t state = 0; state < dfa_states.size(); ++state) { | 341 | 18 | if (!active_states[state]) { | 342 | 9 | continue; | 343 | 9 | } | 344 | | | 345 | 9 | switch (dfa_states[state].transition) { | 346 | 0 | case DFATransition::None: | 347 | 0 | break; | 348 | 0 | case DFATransition::AnyEvent: | 349 | 0 | next_active_states[state + 1] = true; | 350 | 0 | ++n_active; | 351 | 0 | break; | 352 | 9 | case DFATransition::SpecificEvent: | 353 | 9 | if (events_it->second.test(dfa_states[state].event)) { | 354 | 6 | next_active_states[state + 1] = true; | 355 | 6 | ++n_active; | 356 | 6 | } | 357 | 9 | break; | 358 | 9 | } | 359 | | | 360 | 9 | if (dfa_states[state].has_kleene) { | 361 | 6 | next_active_states[state] = true; | 362 | 6 | ++n_active; | 363 | 6 | } | 364 | 9 | } | 365 | 6 | swap(active_states, next_active_states); | 366 | 6 | } | 367 | | | 368 | 3 | return active_states.back(); | 369 | 3 | } |
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE9dfa_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ |
370 | | |
371 | | template <typename EventEntry> |
372 | 7 | bool backtracking_match(EventEntry& events_it, const EventEntry events_end) const { |
373 | 7 | const auto action_begin = std::begin(actions); |
374 | 7 | const auto action_end = std::end(actions); |
375 | 7 | auto action_it = action_begin; |
376 | | |
377 | 7 | const auto events_begin = events_it; |
378 | 7 | auto base_it = events_it; |
379 | | |
380 | | /// an iterator to action plus an iterator to row in events list plus timestamp at the start of sequence |
381 | 7 | using backtrack_info = std::tuple<decltype(action_it), EventEntry, EventEntry>; |
382 | 7 | std::stack<backtrack_info> back_stack; |
383 | | |
384 | | /// backtrack if possible |
385 | 7 | const auto do_backtrack = [&] { |
386 | 0 | while (!back_stack.empty()) { |
387 | 0 | auto& top = back_stack.top(); |
388 | |
|
389 | 0 | action_it = std::get<0>(top); |
390 | 0 | events_it = std::next(std::get<1>(top)); |
391 | 0 | base_it = std::get<2>(top); |
392 | |
|
393 | 0 | back_stack.pop(); |
394 | |
|
395 | 0 | if (events_it != events_end) return true; |
396 | 0 | } |
397 | | |
398 | 0 | return false; |
399 | 0 | }; Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ENKUlvE_clEv Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ENKUlvE_clEv Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ENKUlvE_clEv Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ENKUlvE_clEv |
400 | | |
401 | 7 | size_t i = 0; |
402 | 28 | while (action_it != action_end && events_it != events_end) { |
403 | 21 | if (action_it->type == PatternActionType::SpecificEvent) { |
404 | 14 | if (events_it->second.test(action_it->extra)) { |
405 | | /// move to the next action and events |
406 | 14 | base_it = events_it; |
407 | 14 | ++action_it, ++events_it; |
408 | 14 | } else if (!do_backtrack()) |
409 | | /// backtracking failed, bail out |
410 | 0 | break; |
411 | 14 | } else if (action_it->type == PatternActionType::AnyEvent) { |
412 | 0 | base_it = events_it; |
413 | 0 | ++action_it, ++events_it; |
414 | 7 | } else if (action_it->type == PatternActionType::KleeneStar) { |
415 | 7 | back_stack.emplace(action_it, events_it, base_it); |
416 | 7 | base_it = events_it; |
417 | 7 | ++action_it; |
418 | 7 | } else if (action_it->type == PatternActionType::TimeLessOrEqual) { |
419 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) <= action_it->extra) { |
420 | | /// condition satisfied, move onto next action |
421 | 0 | back_stack.emplace(action_it, events_it, base_it); |
422 | 0 | base_it = events_it; |
423 | 0 | ++action_it; |
424 | 0 | } else if (!do_backtrack()) |
425 | 0 | break; |
426 | 0 | } else if (action_it->type == PatternActionType::TimeLess) { |
427 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) < action_it->extra) { |
428 | 0 | back_stack.emplace(action_it, events_it, base_it); |
429 | 0 | base_it = events_it; |
430 | 0 | ++action_it; |
431 | 0 | } else if (!do_backtrack()) |
432 | 0 | break; |
433 | 0 | } else if (action_it->type == PatternActionType::TimeGreaterOrEqual) { |
434 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) >= action_it->extra) { |
435 | 0 | back_stack.emplace(action_it, events_it, base_it); |
436 | 0 | base_it = events_it; |
437 | 0 | ++action_it; |
438 | 0 | } else if (++events_it == events_end && !do_backtrack()) |
439 | 0 | break; |
440 | 0 | } else if (action_it->type == PatternActionType::TimeGreater) { |
441 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) > action_it->extra) { |
442 | 0 | back_stack.emplace(action_it, events_it, base_it); |
443 | 0 | base_it = events_it; |
444 | 0 | ++action_it; |
445 | 0 | } else if (++events_it == events_end && !do_backtrack()) |
446 | 0 | break; |
447 | 0 | } else if (action_it->type == PatternActionType::TimeEqual) { |
448 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) == action_it->extra) { |
449 | 0 | back_stack.emplace(action_it, events_it, base_it); |
450 | 0 | base_it = events_it; |
451 | 0 | ++action_it; |
452 | 0 | } else if (++events_it == events_end && !do_backtrack()) |
453 | 0 | break; |
454 | 0 | } else { |
455 | 0 | LOG(WARNING) << "Unknown PatternActionType"; |
456 | 0 | return false; |
457 | 0 | } |
458 | | |
459 | 21 | if (++i > sequence_match_max_iterations) { |
460 | 0 | LOG(WARNING) |
461 | 0 | << "Pattern application proves too difficult, exceeding max iterations (" + |
462 | 0 | std::to_string(sequence_match_max_iterations) + ")"; |
463 | 0 | return false; |
464 | 0 | } |
465 | 21 | } |
466 | | |
467 | | /// if there are some actions remaining |
468 | 7 | if (action_it != action_end) { |
469 | | /// match multiple empty strings at end |
470 | 0 | while (action_it->type == PatternActionType::KleeneStar || |
471 | 0 | action_it->type == PatternActionType::TimeLessOrEqual || |
472 | 0 | action_it->type == PatternActionType::TimeLess || |
473 | 0 | (action_it->type == PatternActionType::TimeGreaterOrEqual && |
474 | 0 | action_it->extra == 0)) |
475 | 0 | ++action_it; |
476 | 0 | } |
477 | | |
478 | 7 | if (events_it == events_begin) ++events_it; |
479 | | |
480 | 7 | return action_it == action_end; |
481 | 7 | } Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ Line | Count | Source | 372 | 7 | bool backtracking_match(EventEntry& events_it, const EventEntry events_end) const { | 373 | 7 | const auto action_begin = std::begin(actions); | 374 | 7 | const auto action_end = std::end(actions); | 375 | 7 | auto action_it = action_begin; | 376 | | | 377 | 7 | const auto events_begin = events_it; | 378 | 7 | auto base_it = events_it; | 379 | | | 380 | | /// an iterator to action plus an iterator to row in events list plus timestamp at the start of sequence | 381 | 7 | using backtrack_info = std::tuple<decltype(action_it), EventEntry, EventEntry>; | 382 | 7 | std::stack<backtrack_info> back_stack; | 383 | | | 384 | | /// backtrack if possible | 385 | 7 | const auto do_backtrack = [&] { | 386 | 7 | while (!back_stack.empty()) { | 387 | 7 | auto& top = back_stack.top(); | 388 | | | 389 | 7 | action_it = std::get<0>(top); | 390 | 7 | events_it = std::next(std::get<1>(top)); | 391 | 7 | base_it = std::get<2>(top); | 392 | | | 393 | 7 | back_stack.pop(); | 394 | | | 395 | 7 | if (events_it != events_end) return true; | 396 | 7 | } | 397 | | | 398 | 7 | return false; | 399 | 7 | }; | 400 | | | 401 | 7 | size_t i = 0; | 402 | 28 | while (action_it != action_end && events_it != events_end) { | 403 | 21 | if (action_it->type == PatternActionType::SpecificEvent) { | 404 | 14 | if (events_it->second.test(action_it->extra)) { | 405 | | /// move to the next action and events | 406 | 14 | base_it = events_it; | 407 | 14 | ++action_it, ++events_it; | 408 | 14 | } else if (!do_backtrack()) | 409 | | /// backtracking failed, bail out | 410 | 0 | break; | 411 | 14 | } else if (action_it->type == PatternActionType::AnyEvent) { | 412 | 0 | base_it = events_it; | 413 | 0 | ++action_it, ++events_it; | 414 | 7 | } else if (action_it->type == PatternActionType::KleeneStar) { | 415 | 7 | back_stack.emplace(action_it, events_it, base_it); | 416 | 7 | base_it = events_it; | 417 | 7 | ++action_it; | 418 | 7 | } else if (action_it->type == PatternActionType::TimeLessOrEqual) { | 419 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) <= action_it->extra) { | 420 | | /// condition satisfied, move onto next action | 421 | 0 | back_stack.emplace(action_it, events_it, base_it); | 422 | 0 | base_it = events_it; | 423 | 0 | ++action_it; | 424 | 0 | } else if (!do_backtrack()) | 425 | 0 | break; | 426 | 0 | } else if (action_it->type == PatternActionType::TimeLess) { | 427 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) < action_it->extra) { | 428 | 0 | back_stack.emplace(action_it, events_it, base_it); | 429 | 0 | base_it = events_it; | 430 | 0 | ++action_it; | 431 | 0 | } else if (!do_backtrack()) | 432 | 0 | break; | 433 | 0 | } else if (action_it->type == PatternActionType::TimeGreaterOrEqual) { | 434 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) >= action_it->extra) { | 435 | 0 | back_stack.emplace(action_it, events_it, base_it); | 436 | 0 | base_it = events_it; | 437 | 0 | ++action_it; | 438 | 0 | } else if (++events_it == events_end && !do_backtrack()) | 439 | 0 | break; | 440 | 0 | } else if (action_it->type == PatternActionType::TimeGreater) { | 441 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) > action_it->extra) { | 442 | 0 | back_stack.emplace(action_it, events_it, base_it); | 443 | 0 | base_it = events_it; | 444 | 0 | ++action_it; | 445 | 0 | } else if (++events_it == events_end && !do_backtrack()) | 446 | 0 | break; | 447 | 0 | } else if (action_it->type == PatternActionType::TimeEqual) { | 448 | 0 | if (events_it->first.datetime_diff_in_seconds(base_it->first) == action_it->extra) { | 449 | 0 | back_stack.emplace(action_it, events_it, base_it); | 450 | 0 | base_it = events_it; | 451 | 0 | ++action_it; | 452 | 0 | } else if (++events_it == events_end && !do_backtrack()) | 453 | 0 | break; | 454 | 0 | } else { | 455 | 0 | LOG(WARNING) << "Unknown PatternActionType"; | 456 | 0 | return false; | 457 | 0 | } | 458 | | | 459 | 21 | if (++i > sequence_match_max_iterations) { | 460 | 0 | LOG(WARNING) | 461 | 0 | << "Pattern application proves too difficult, exceeding max iterations (" + | 462 | 0 | std::to_string(sequence_match_max_iterations) + ")"; | 463 | 0 | return false; | 464 | 0 | } | 465 | 21 | } | 466 | | | 467 | | /// if there are some actions remaining | 468 | 7 | if (action_it != action_end) { | 469 | | /// match multiple empty strings at end | 470 | 0 | while (action_it->type == PatternActionType::KleeneStar || | 471 | 0 | action_it->type == PatternActionType::TimeLessOrEqual || | 472 | 0 | action_it->type == PatternActionType::TimeLess || | 473 | 0 | (action_it->type == PatternActionType::TimeGreaterOrEqual && | 474 | 0 | action_it->extra == 0)) | 475 | 0 | ++action_it; | 476 | 0 | } | 477 | | | 478 | 7 | if (events_it == events_begin) ++events_it; | 479 | | | 480 | 7 | return action_it == action_end; | 481 | 7 | } |
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE18backtracking_matchIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbRT_SL_ |
482 | | |
483 | | /// Splits the pattern into deterministic parts separated by non-deterministic fragments |
484 | | /// (time constraints and Kleene stars), and tries to match the deterministic parts in their specified order, |
485 | | /// ignoring the non-deterministic fragments. |
486 | | /// This function can quickly check that a full match is not possible if some deterministic fragment is missing. |
487 | | template <typename EventEntry> |
488 | | bool could_match_deterministic_parts(const EventEntry events_begin, const EventEntry events_end, |
489 | 4 | bool limit_iterations = true) const { |
490 | 4 | size_t events_processed = 0; |
491 | 4 | auto events_it = events_begin; |
492 | | |
493 | 4 | const auto actions_end = std::end(actions); |
494 | 4 | auto actions_it = std::begin(actions); |
495 | 4 | auto det_part_begin = actions_it; |
496 | | |
497 | 4 | auto match_deterministic_part = [&events_it, events_end, &events_processed, det_part_begin, |
498 | 8 | actions_it, limit_iterations]() { |
499 | 8 | auto events_it_init = events_it; |
500 | 8 | auto det_part_it = det_part_begin; |
501 | | |
502 | 8 | while (det_part_it != actions_it && events_it != events_end) { |
503 | | /// matching any event |
504 | 0 | if (det_part_it->type == PatternActionType::AnyEvent) ++events_it, ++det_part_it; |
505 | | |
506 | | /// matching specific event |
507 | 0 | else { |
508 | 0 | if (events_it->second.test(det_part_it->extra)) ++events_it, ++det_part_it; |
509 | | |
510 | | /// abandon current matching, try to match the deterministic fragment further in the list |
511 | 0 | else { |
512 | 0 | events_it = ++events_it_init; |
513 | 0 | det_part_it = det_part_begin; |
514 | 0 | } |
515 | 0 | } |
516 | |
|
517 | 0 | if (limit_iterations && ++events_processed > sequence_match_max_iterations) { |
518 | 0 | LOG(WARNING) << "Pattern application proves too difficult, exceeding max " |
519 | 0 | "iterations are " + |
520 | 0 | std::to_string(sequence_match_max_iterations); |
521 | 0 | return false; |
522 | 0 | } |
523 | 0 | } |
524 | | |
525 | 8 | return det_part_it == actions_it; |
526 | 8 | }; Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_bENKUlvE_clEv Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_bENKUlvE_clEv _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_bENKUlvE_clEv Line | Count | Source | 498 | 8 | actions_it, limit_iterations]() { | 499 | 8 | auto events_it_init = events_it; | 500 | 8 | auto det_part_it = det_part_begin; | 501 | | | 502 | 8 | while (det_part_it != actions_it && events_it != events_end) { | 503 | | /// matching any event | 504 | 0 | if (det_part_it->type == PatternActionType::AnyEvent) ++events_it, ++det_part_it; | 505 | | | 506 | | /// matching specific event | 507 | 0 | else { | 508 | 0 | if (events_it->second.test(det_part_it->extra)) ++events_it, ++det_part_it; | 509 | | | 510 | | /// abandon current matching, try to match the deterministic fragment further in the list | 511 | 0 | else { | 512 | 0 | events_it = ++events_it_init; | 513 | 0 | det_part_it = det_part_begin; | 514 | 0 | } | 515 | 0 | } | 516 | |
| 517 | 0 | if (limit_iterations && ++events_processed > sequence_match_max_iterations) { | 518 | 0 | LOG(WARNING) << "Pattern application proves too difficult, exceeding max " | 519 | 0 | "iterations are " + | 520 | 0 | std::to_string(sequence_match_max_iterations); | 521 | 0 | return false; | 522 | 0 | } | 523 | 0 | } | 524 | | | 525 | 8 | return det_part_it == actions_it; | 526 | 8 | }; |
Unexecuted instantiation: _ZZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_bENKUlvE_clEv |
527 | | |
528 | 16 | for (; actions_it != actions_end; ++actions_it) |
529 | 12 | if (actions_it->type != PatternActionType::SpecificEvent && |
530 | 12 | actions_it->type != PatternActionType::AnyEvent) { |
531 | 4 | if (!match_deterministic_part()) return false; |
532 | 4 | det_part_begin = std::next(actions_it); |
533 | 4 | } |
534 | | |
535 | 4 | return match_deterministic_part(); |
536 | 4 | } Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_b Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_b _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_19DateTimeV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_b Line | Count | Source | 489 | 4 | bool limit_iterations = true) const { | 490 | 4 | size_t events_processed = 0; | 491 | 4 | auto events_it = events_begin; | 492 | | | 493 | 4 | const auto actions_end = std::end(actions); | 494 | 4 | auto actions_it = std::begin(actions); | 495 | 4 | auto det_part_begin = actions_it; | 496 | | | 497 | 4 | auto match_deterministic_part = [&events_it, events_end, &events_processed, det_part_begin, | 498 | 4 | actions_it, limit_iterations]() { | 499 | 4 | auto events_it_init = events_it; | 500 | 4 | auto det_part_it = det_part_begin; | 501 | | | 502 | 4 | while (det_part_it != actions_it && events_it != events_end) { | 503 | | /// matching any event | 504 | 4 | if (det_part_it->type == PatternActionType::AnyEvent) ++events_it, ++det_part_it; | 505 | | | 506 | | /// matching specific event | 507 | 4 | else { | 508 | 4 | if (events_it->second.test(det_part_it->extra)) ++events_it, ++det_part_it; | 509 | | | 510 | | /// abandon current matching, try to match the deterministic fragment further in the list | 511 | 4 | else { | 512 | 4 | events_it = ++events_it_init; | 513 | 4 | det_part_it = det_part_begin; | 514 | 4 | } | 515 | 4 | } | 516 | | | 517 | 4 | if (limit_iterations && ++events_processed > sequence_match_max_iterations) { | 518 | 4 | LOG(WARNING) << "Pattern application proves too difficult, exceeding max " | 519 | 4 | "iterations are " + | 520 | 4 | std::to_string(sequence_match_max_iterations); | 521 | 4 | return false; | 522 | 4 | } | 523 | 4 | } | 524 | | | 525 | 4 | return det_part_it == actions_it; | 526 | 4 | }; | 527 | | | 528 | 16 | for (; actions_it != actions_end; ++actions_it) | 529 | 12 | if (actions_it->type != PatternActionType::SpecificEvent && | 530 | 12 | actions_it->type != PatternActionType::AnyEvent) { | 531 | 4 | if (!match_deterministic_part()) return false; | 532 | 4 | det_part_begin = std::next(actions_it); | 533 | 4 | } | 534 | | | 535 | 4 | return match_deterministic_part(); | 536 | 4 | } |
Unexecuted instantiation: _ZNK5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE31could_match_deterministic_partsIN9__gnu_cxx17__normal_iteratorIPKSt4pairINS_11DateV2ValueINS_15DateV2ValueTypeEEESt6bitsetILm32EEESt6vectorISE_SaISE_EEEEEEbT_SL_b |
537 | | |
538 | | private: |
539 | | enum class DFATransition : char { |
540 | | /// .-------. |
541 | | /// | | |
542 | | /// `-------' |
543 | | None, |
544 | | /// .-------. (?[0-9]) |
545 | | /// | | ---------- |
546 | | /// `-------' |
547 | | SpecificEvent, |
548 | | /// .-------. . |
549 | | /// | | ---------- |
550 | | /// `-------' |
551 | | AnyEvent, |
552 | | }; |
553 | | |
554 | | struct DFAState { |
555 | | explicit DFAState(bool has_kleene_ = false) |
556 | 32 | : has_kleene {has_kleene_}, event {0}, transition {DFATransition::None} {}_ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE8DFAStateC2Eb Line | Count | Source | 556 | 16 | : has_kleene {has_kleene_}, event {0}, transition {DFATransition::None} {} |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE8DFAStateC2Eb _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE8DFAStateC2Eb Line | Count | Source | 556 | 16 | : has_kleene {has_kleene_}, event {0}, transition {DFATransition::None} {} |
Unexecuted instantiation: _ZN5doris34AggregateFunctionSequenceMatchDataILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE8DFAStateC2Eb |
557 | | |
558 | | /// .-------. |
559 | | /// | | - - - |
560 | | /// `-------' |
561 | | /// |_^ |
562 | | bool has_kleene; |
563 | | /// In the case of a state transitions with a `SpecificEvent`, |
564 | | /// `event` contains the value of the event. |
565 | | uint32_t event; |
566 | | /// The kind of transition out of this state. |
567 | | DFATransition transition; |
568 | | }; |
569 | | |
570 | | using DFAStates = std::vector<DFAState>; |
571 | | |
572 | | public: |
573 | | bool sorted = true; |
574 | | std::vector<TimestampEvents> events_list; |
575 | | // sequenceMatch conditions met at least once in events_list |
576 | | std::bitset<MAX_EVENTS> conditions_met; |
577 | | // sequenceMatch conditions met at least once in the pattern |
578 | | std::bitset<MAX_EVENTS> conditions_in_pattern; |
579 | | // `True` if the parsed pattern contains time assertions (?t...), `false` otherwise. |
580 | | bool pattern_has_time; |
581 | | |
582 | | private: |
583 | | std::string pattern; |
584 | | size_t arg_count; |
585 | | bool init_flag = false; |
586 | | |
587 | | PatternActions actions; |
588 | | DFAStates dfa_states; |
589 | | }; |
590 | | |
591 | | template <PrimitiveType T, typename Derived> |
592 | | class AggregateFunctionSequenceBase |
593 | | : public IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData<T, Derived>, |
594 | | Derived> { |
595 | | public: |
596 | | using NativeType = typename PrimitiveTypeTraits<T>::CppType; |
597 | | AggregateFunctionSequenceBase(const DataTypes& arguments) |
598 | 15 | : IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData<T, Derived>, Derived>( |
599 | 15 | arguments) { |
600 | 15 | arg_count = arguments.size(); |
601 | 15 | } _ZN5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEEC2ERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE Line | Count | Source | 598 | 7 | : IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData<T, Derived>, Derived>( | 599 | 7 | arguments) { | 600 | 7 | arg_count = arguments.size(); | 601 | 7 | } |
Unexecuted instantiation: _ZN5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEEC2ERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE _ZN5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEEC2ERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE Line | Count | Source | 598 | 8 | : IAggregateFunctionDataHelper<AggregateFunctionSequenceMatchData<T, Derived>, Derived>( | 599 | 8 | arguments) { | 600 | 8 | arg_count = arguments.size(); | 601 | 8 | } |
Unexecuted instantiation: _ZN5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEEC2ERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE |
602 | | |
603 | 0 | void reset(AggregateDataPtr __restrict place) const override { this->data(place).reset(); }Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5resetEPc Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5resetEPc Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5resetEPc Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5resetEPc |
604 | | |
605 | | void add(AggregateDataPtr __restrict place, const IColumn** columns, const ssize_t row_num, |
606 | 16 | Arena&) const override { |
607 | 16 | std::string pattern = |
608 | 16 | assert_cast<const ColumnString*, TypeCheckOnRelease::DISABLE>(columns[0]) |
609 | 16 | ->get_data_at(0) |
610 | 16 | .to_string(); |
611 | 16 | this->data(place).init(pattern, arg_count); |
612 | | |
613 | 16 | const auto& timestamp = assert_cast<const typename PrimitiveTypeTraits<T>::ColumnType&, |
614 | 16 | TypeCheckOnRelease::DISABLE>(*columns[1]) |
615 | 16 | .get_data()[row_num]; |
616 | 16 | typename AggregateFunctionSequenceMatchData<T, Derived>::Events events; |
617 | | |
618 | 52 | for (auto i = 2; i < arg_count; i++) { |
619 | 36 | const auto event = |
620 | 36 | assert_cast<const ColumnUInt8*, TypeCheckOnRelease::DISABLE>(columns[i]) |
621 | 36 | ->get_data()[row_num]; |
622 | 36 | events.set(i - 2, event); |
623 | 36 | } |
624 | | |
625 | 16 | this->data(place).add(timestamp, events); |
626 | 16 | } _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE3addEPcPPKNS_7IColumnElRNS_5ArenaE Line | Count | Source | 606 | 8 | Arena&) const override { | 607 | 8 | std::string pattern = | 608 | 8 | assert_cast<const ColumnString*, TypeCheckOnRelease::DISABLE>(columns[0]) | 609 | 8 | ->get_data_at(0) | 610 | 8 | .to_string(); | 611 | 8 | this->data(place).init(pattern, arg_count); | 612 | | | 613 | 8 | const auto& timestamp = assert_cast<const typename PrimitiveTypeTraits<T>::ColumnType&, | 614 | 8 | TypeCheckOnRelease::DISABLE>(*columns[1]) | 615 | 8 | .get_data()[row_num]; | 616 | 8 | typename AggregateFunctionSequenceMatchData<T, Derived>::Events events; | 617 | | | 618 | 28 | for (auto i = 2; i < arg_count; i++) { | 619 | 20 | const auto event = | 620 | 20 | assert_cast<const ColumnUInt8*, TypeCheckOnRelease::DISABLE>(columns[i]) | 621 | 20 | ->get_data()[row_num]; | 622 | 20 | events.set(i - 2, event); | 623 | 20 | } | 624 | | | 625 | 8 | this->data(place).add(timestamp, events); | 626 | 8 | } |
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE3addEPcPPKNS_7IColumnElRNS_5ArenaE _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE3addEPcPPKNS_7IColumnElRNS_5ArenaE Line | Count | Source | 606 | 8 | Arena&) const override { | 607 | 8 | std::string pattern = | 608 | 8 | assert_cast<const ColumnString*, TypeCheckOnRelease::DISABLE>(columns[0]) | 609 | 8 | ->get_data_at(0) | 610 | 8 | .to_string(); | 611 | 8 | this->data(place).init(pattern, arg_count); | 612 | | | 613 | 8 | const auto& timestamp = assert_cast<const typename PrimitiveTypeTraits<T>::ColumnType&, | 614 | 8 | TypeCheckOnRelease::DISABLE>(*columns[1]) | 615 | 8 | .get_data()[row_num]; | 616 | 8 | typename AggregateFunctionSequenceMatchData<T, Derived>::Events events; | 617 | | | 618 | 24 | for (auto i = 2; i < arg_count; i++) { | 619 | 16 | const auto event = | 620 | 16 | assert_cast<const ColumnUInt8*, TypeCheckOnRelease::DISABLE>(columns[i]) | 621 | 16 | ->get_data()[row_num]; | 622 | 16 | events.set(i - 2, event); | 623 | 16 | } | 624 | | | 625 | 8 | this->data(place).add(timestamp, events); | 626 | 8 | } |
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE3addEPcPPKNS_7IColumnElRNS_5ArenaE |
627 | | |
628 | | void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs, |
629 | 4 | Arena&) const override { |
630 | 4 | const std::string pattern = this->data(rhs).get_pattern(); |
631 | 4 | this->data(place).init(pattern, this->data(rhs).get_arg_count()); |
632 | 4 | this->data(place).merge(this->data(rhs)); |
633 | 4 | } _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE5mergeEPcPKcRNS_5ArenaE Line | Count | Source | 629 | 2 | Arena&) const override { | 630 | 2 | const std::string pattern = this->data(rhs).get_pattern(); | 631 | 2 | this->data(place).init(pattern, this->data(rhs).get_arg_count()); | 632 | 2 | this->data(place).merge(this->data(rhs)); | 633 | 2 | } |
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE5mergeEPcPKcRNS_5ArenaE _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE5mergeEPcPKcRNS_5ArenaE Line | Count | Source | 629 | 2 | Arena&) const override { | 630 | 2 | const std::string pattern = this->data(rhs).get_pattern(); | 631 | 2 | this->data(place).init(pattern, this->data(rhs).get_arg_count()); | 632 | 2 | this->data(place).merge(this->data(rhs)); | 633 | 2 | } |
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE5mergeEPcPKcRNS_5ArenaE |
634 | | |
635 | 6 | void serialize(ConstAggregateDataPtr __restrict place, BufferWritable& buf) const override { |
636 | 6 | this->data(place).write(buf); |
637 | 6 | } _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE9serializeEPKcRNS_14BufferWritableE Line | Count | Source | 635 | 3 | void serialize(ConstAggregateDataPtr __restrict place, BufferWritable& buf) const override { | 636 | 3 | this->data(place).write(buf); | 637 | 3 | } |
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE9serializeEPKcRNS_14BufferWritableE _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE9serializeEPKcRNS_14BufferWritableE Line | Count | Source | 635 | 3 | void serialize(ConstAggregateDataPtr __restrict place, BufferWritable& buf) const override { | 636 | 3 | this->data(place).write(buf); | 637 | 3 | } |
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE9serializeEPKcRNS_14BufferWritableE |
638 | | |
639 | | void deserialize(AggregateDataPtr __restrict place, BufferReadable& buf, |
640 | 6 | Arena&) const override { |
641 | 6 | this->data(place).read(buf); |
642 | 6 | const std::string pattern = this->data(place).get_pattern(); |
643 | 6 | this->data(place).init(pattern, this->data(place).get_arg_count()); |
644 | 6 | } _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceMatchILS1_26EEEE11deserializeEPcRNS_14BufferReadableERNS_5ArenaE Line | Count | Source | 640 | 3 | Arena&) const override { | 641 | 3 | this->data(place).read(buf); | 642 | 3 | const std::string pattern = this->data(place).get_pattern(); | 643 | 3 | this->data(place).init(pattern, this->data(place).get_arg_count()); | 644 | 3 | } |
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceMatchILS1_25EEEE11deserializeEPcRNS_14BufferReadableERNS_5ArenaE _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE26ENS_30AggregateFunctionSequenceCountILS1_26EEEE11deserializeEPcRNS_14BufferReadableERNS_5ArenaE Line | Count | Source | 640 | 3 | Arena&) const override { | 641 | 3 | this->data(place).read(buf); | 642 | 3 | const std::string pattern = this->data(place).get_pattern(); | 643 | 3 | this->data(place).init(pattern, this->data(place).get_arg_count()); | 644 | 3 | } |
Unexecuted instantiation: _ZNK5doris29AggregateFunctionSequenceBaseILNS_13PrimitiveTypeE25ENS_30AggregateFunctionSequenceCountILS1_25EEEE11deserializeEPcRNS_14BufferReadableERNS_5ArenaE |
645 | | |
646 | | private: |
647 | | size_t arg_count; |
648 | | }; |
649 | | |
650 | | template <PrimitiveType T> |
651 | | class AggregateFunctionSequenceMatch final |
652 | | : public AggregateFunctionSequenceBase<T, AggregateFunctionSequenceMatch<T>>, |
653 | | VarargsExpression, |
654 | | NullableAggregateFunction { |
655 | | public: |
656 | | AggregateFunctionSequenceMatch(const DataTypes& arguments, const String& pattern_) |
657 | | : AggregateFunctionSequenceBase<T, AggregateFunctionSequenceMatch<T>>(arguments, |
658 | | pattern_) {} |
659 | | |
660 | | using AggregateFunctionSequenceBase< |
661 | | T, AggregateFunctionSequenceMatch<T>>::AggregateFunctionSequenceBase; |
662 | | |
663 | 0 | String get_name() const override { return "sequence_match"; }Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE26EE8get_nameB5cxx11Ev Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE25EE8get_nameB5cxx11Ev |
664 | | |
665 | 0 | DataTypePtr get_return_type() const override { return std::make_shared<DataTypeUInt8>(); }Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE26EE15get_return_typeEv Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE25EE15get_return_typeEv |
666 | | |
667 | 6 | void insert_result_into(ConstAggregateDataPtr __restrict place, IColumn& to) const override { |
668 | 6 | auto& output = assert_cast<ColumnUInt8&>(to).get_data(); |
669 | 6 | if (!this->data(place).conditions_in_pattern.any()) { |
670 | 2 | output.push_back(false); |
671 | 2 | return; |
672 | 2 | } |
673 | | |
674 | 4 | if ((this->data(place).conditions_in_pattern & this->data(place).conditions_met) != |
675 | 4 | this->data(place).conditions_in_pattern) { |
676 | 1 | output.push_back(false); |
677 | 1 | return; |
678 | 1 | } |
679 | | // place is essentially an AggregateDataPtr, passed as a ConstAggregateDataPtr. |
680 | 3 | this->data(const_cast<AggregateDataPtr>(place)).sort(); |
681 | | |
682 | 3 | const auto& data_ref = this->data(place); |
683 | | |
684 | 3 | const auto events_begin = std::begin(data_ref.events_list); |
685 | 3 | const auto events_end = std::end(data_ref.events_list); |
686 | 3 | auto events_it = events_begin; |
687 | | |
688 | 3 | bool match = (this->data(place).pattern_has_time |
689 | 3 | ? (this->data(place).could_match_deterministic_parts(events_begin, |
690 | 0 | events_end) && |
691 | 0 | this->data(place).backtracking_match(events_it, events_end)) |
692 | 3 | : this->data(place).dfa_match(events_it, events_end)); |
693 | 3 | output.push_back(match); |
694 | 3 | } _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE26EE18insert_result_intoEPKcRNS_7IColumnE Line | Count | Source | 667 | 6 | void insert_result_into(ConstAggregateDataPtr __restrict place, IColumn& to) const override { | 668 | 6 | auto& output = assert_cast<ColumnUInt8&>(to).get_data(); | 669 | 6 | if (!this->data(place).conditions_in_pattern.any()) { | 670 | 2 | output.push_back(false); | 671 | 2 | return; | 672 | 2 | } | 673 | | | 674 | 4 | if ((this->data(place).conditions_in_pattern & this->data(place).conditions_met) != | 675 | 4 | this->data(place).conditions_in_pattern) { | 676 | 1 | output.push_back(false); | 677 | 1 | return; | 678 | 1 | } | 679 | | // place is essentially an AggregateDataPtr, passed as a ConstAggregateDataPtr. | 680 | 3 | this->data(const_cast<AggregateDataPtr>(place)).sort(); | 681 | | | 682 | 3 | const auto& data_ref = this->data(place); | 683 | | | 684 | 3 | const auto events_begin = std::begin(data_ref.events_list); | 685 | 3 | const auto events_end = std::end(data_ref.events_list); | 686 | 3 | auto events_it = events_begin; | 687 | | | 688 | 3 | bool match = (this->data(place).pattern_has_time | 689 | 3 | ? (this->data(place).could_match_deterministic_parts(events_begin, | 690 | 0 | events_end) && | 691 | 0 | this->data(place).backtracking_match(events_it, events_end)) | 692 | 3 | : this->data(place).dfa_match(events_it, events_end)); | 693 | 3 | output.push_back(match); | 694 | 3 | } |
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceMatchILNS_13PrimitiveTypeE25EE18insert_result_intoEPKcRNS_7IColumnE |
695 | | }; |
696 | | |
697 | | template <PrimitiveType T> |
698 | | class AggregateFunctionSequenceCount final |
699 | | : public AggregateFunctionSequenceBase<T, AggregateFunctionSequenceCount<T>>, |
700 | | VarargsExpression, |
701 | | NotNullableAggregateFunction { |
702 | | public: |
703 | | AggregateFunctionSequenceCount(const DataTypes& arguments, const String& pattern_) |
704 | | : AggregateFunctionSequenceBase<T, AggregateFunctionSequenceCount<T>>(arguments, |
705 | | pattern_) {} |
706 | | |
707 | | using AggregateFunctionSequenceBase< |
708 | | T, AggregateFunctionSequenceCount<T>>::AggregateFunctionSequenceBase; |
709 | | |
710 | 0 | String get_name() const override { return "sequence_count"; }Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE26EE8get_nameB5cxx11Ev Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE25EE8get_nameB5cxx11Ev |
711 | | |
712 | 0 | DataTypePtr get_return_type() const override { return std::make_shared<DataTypeInt64>(); }Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE26EE15get_return_typeEv Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE25EE15get_return_typeEv |
713 | | |
714 | 6 | void insert_result_into(ConstAggregateDataPtr __restrict place, IColumn& to) const override { |
715 | 6 | auto& output = assert_cast<ColumnInt64&>(to).get_data(); |
716 | 6 | if (!this->data(place).conditions_in_pattern.any()) { |
717 | 2 | output.push_back(0); |
718 | 2 | return; |
719 | 2 | } |
720 | | |
721 | 4 | if ((this->data(place).conditions_in_pattern & this->data(place).conditions_met) != |
722 | 4 | this->data(place).conditions_in_pattern) { |
723 | 0 | output.push_back(0); |
724 | 0 | return; |
725 | 0 | } |
726 | | // place is essentially an AggregateDataPtr, passed as a ConstAggregateDataPtr. |
727 | 4 | this->data(const_cast<AggregateDataPtr>(place)).sort(); |
728 | 4 | output.push_back(count(place)); |
729 | 4 | } _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE26EE18insert_result_intoEPKcRNS_7IColumnE Line | Count | Source | 714 | 6 | void insert_result_into(ConstAggregateDataPtr __restrict place, IColumn& to) const override { | 715 | 6 | auto& output = assert_cast<ColumnInt64&>(to).get_data(); | 716 | 6 | if (!this->data(place).conditions_in_pattern.any()) { | 717 | 2 | output.push_back(0); | 718 | 2 | return; | 719 | 2 | } | 720 | | | 721 | 4 | if ((this->data(place).conditions_in_pattern & this->data(place).conditions_met) != | 722 | 4 | this->data(place).conditions_in_pattern) { | 723 | 0 | output.push_back(0); | 724 | 0 | return; | 725 | 0 | } | 726 | | // place is essentially an AggregateDataPtr, passed as a ConstAggregateDataPtr. | 727 | 4 | this->data(const_cast<AggregateDataPtr>(place)).sort(); | 728 | 4 | output.push_back(count(place)); | 729 | 4 | } |
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE25EE18insert_result_intoEPKcRNS_7IColumnE |
730 | | |
731 | | private: |
732 | 4 | UInt64 count(ConstAggregateDataPtr __restrict place) const { |
733 | 4 | const auto& data_ref = this->data(place); |
734 | | |
735 | 4 | const auto events_begin = std::begin(data_ref.events_list); |
736 | 4 | const auto events_end = std::end(data_ref.events_list); |
737 | 4 | auto events_it = events_begin; |
738 | | |
739 | 4 | size_t count = 0; |
740 | | // check if there is a chance of matching the sequence at least once |
741 | 4 | if (this->data(place).could_match_deterministic_parts(events_begin, events_end)) { |
742 | 11 | while (events_it != events_end && |
743 | 11 | this->data(place).backtracking_match(events_it, events_end)) |
744 | 7 | ++count; |
745 | 4 | } |
746 | | |
747 | 4 | return count; |
748 | 4 | } _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE26EE5countEPKc Line | Count | Source | 732 | 4 | UInt64 count(ConstAggregateDataPtr __restrict place) const { | 733 | 4 | const auto& data_ref = this->data(place); | 734 | | | 735 | 4 | const auto events_begin = std::begin(data_ref.events_list); | 736 | 4 | const auto events_end = std::end(data_ref.events_list); | 737 | 4 | auto events_it = events_begin; | 738 | | | 739 | 4 | size_t count = 0; | 740 | | // check if there is a chance of matching the sequence at least once | 741 | 4 | if (this->data(place).could_match_deterministic_parts(events_begin, events_end)) { | 742 | 11 | while (events_it != events_end && | 743 | 11 | this->data(place).backtracking_match(events_it, events_end)) | 744 | 7 | ++count; | 745 | 4 | } | 746 | | | 747 | 4 | return count; | 748 | 4 | } |
Unexecuted instantiation: _ZNK5doris30AggregateFunctionSequenceCountILNS_13PrimitiveTypeE25EE5countEPKc |
749 | | }; |
750 | | |
751 | | } // namespace doris |
752 | | |
753 | | #include "common/compile_check_end.h" |