grpc 1.31.0.pre1 → 1.31.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +2 -2
- data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +3 -4
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc +5 -4
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/third_party/re2/re2/bitmap256.h +117 -0
- data/third_party/re2/re2/bitstate.cc +385 -0
- data/third_party/re2/re2/compile.cc +1279 -0
- data/third_party/re2/re2/dfa.cc +2130 -0
- data/third_party/re2/re2/filtered_re2.cc +121 -0
- data/third_party/re2/re2/filtered_re2.h +109 -0
- data/third_party/re2/re2/mimics_pcre.cc +197 -0
- data/third_party/re2/re2/nfa.cc +713 -0
- data/third_party/re2/re2/onepass.cc +623 -0
- data/third_party/re2/re2/parse.cc +2464 -0
- data/third_party/re2/re2/perl_groups.cc +119 -0
- data/third_party/re2/re2/pod_array.h +55 -0
- data/third_party/re2/re2/prefilter.cc +710 -0
- data/third_party/re2/re2/prefilter.h +108 -0
- data/third_party/re2/re2/prefilter_tree.cc +407 -0
- data/third_party/re2/re2/prefilter_tree.h +139 -0
- data/third_party/re2/re2/prog.cc +988 -0
- data/third_party/re2/re2/prog.h +436 -0
- data/third_party/re2/re2/re2.cc +1362 -0
- data/third_party/re2/re2/re2.h +1002 -0
- data/third_party/re2/re2/regexp.cc +980 -0
- data/third_party/re2/re2/regexp.h +659 -0
- data/third_party/re2/re2/set.cc +154 -0
- data/third_party/re2/re2/set.h +80 -0
- data/third_party/re2/re2/simplify.cc +657 -0
- data/third_party/re2/re2/sparse_array.h +392 -0
- data/third_party/re2/re2/sparse_set.h +264 -0
- data/third_party/re2/re2/stringpiece.cc +65 -0
- data/third_party/re2/re2/stringpiece.h +210 -0
- data/third_party/re2/re2/tostring.cc +351 -0
- data/third_party/re2/re2/unicode_casefold.cc +582 -0
- data/third_party/re2/re2/unicode_casefold.h +78 -0
- data/third_party/re2/re2/unicode_groups.cc +6269 -0
- data/third_party/re2/re2/unicode_groups.h +67 -0
- data/third_party/re2/re2/walker-inl.h +246 -0
- data/third_party/re2/util/benchmark.h +156 -0
- data/third_party/re2/util/flags.h +26 -0
- data/third_party/re2/util/logging.h +109 -0
- data/third_party/re2/util/malloc_counter.h +19 -0
- data/third_party/re2/util/mix.h +41 -0
- data/third_party/re2/util/mutex.h +148 -0
- data/third_party/re2/util/pcre.cc +1025 -0
- data/third_party/re2/util/pcre.h +681 -0
- data/third_party/re2/util/rune.cc +260 -0
- data/third_party/re2/util/strutil.cc +149 -0
- data/third_party/re2/util/strutil.h +21 -0
- data/third_party/re2/util/test.h +50 -0
- data/third_party/re2/util/utf.h +44 -0
- data/third_party/re2/util/util.h +42 -0
- metadata +78 -29
@@ -0,0 +1,108 @@
|
|
1
|
+
// Copyright 2009 The RE2 Authors. All Rights Reserved.
|
2
|
+
// Use of this source code is governed by a BSD-style
|
3
|
+
// license that can be found in the LICENSE file.
|
4
|
+
|
5
|
+
#ifndef RE2_PREFILTER_H_
|
6
|
+
#define RE2_PREFILTER_H_
|
7
|
+
|
8
|
+
// Prefilter is the class used to extract string guards from regexps.
|
9
|
+
// Rather than using Prefilter class directly, use FilteredRE2.
|
10
|
+
// See filtered_re2.h
|
11
|
+
|
12
|
+
#include <set>
|
13
|
+
#include <string>
|
14
|
+
#include <vector>
|
15
|
+
|
16
|
+
#include "util/util.h"
|
17
|
+
#include "util/logging.h"
|
18
|
+
|
19
|
+
namespace re2 {
|
20
|
+
|
21
|
+
class RE2;
|
22
|
+
|
23
|
+
class Regexp;
|
24
|
+
|
25
|
+
class Prefilter {
|
26
|
+
// Instead of using Prefilter directly, use FilteredRE2; see filtered_re2.h
|
27
|
+
public:
|
28
|
+
enum Op {
|
29
|
+
ALL = 0, // Everything matches
|
30
|
+
NONE, // Nothing matches
|
31
|
+
ATOM, // The string atom() must match
|
32
|
+
AND, // All in subs() must match
|
33
|
+
OR, // One of subs() must match
|
34
|
+
};
|
35
|
+
|
36
|
+
explicit Prefilter(Op op);
|
37
|
+
~Prefilter();
|
38
|
+
|
39
|
+
Op op() { return op_; }
|
40
|
+
const std::string& atom() const { return atom_; }
|
41
|
+
void set_unique_id(int id) { unique_id_ = id; }
|
42
|
+
int unique_id() const { return unique_id_; }
|
43
|
+
|
44
|
+
// The children of the Prefilter node.
|
45
|
+
std::vector<Prefilter*>* subs() {
|
46
|
+
DCHECK(op_ == AND || op_ == OR);
|
47
|
+
return subs_;
|
48
|
+
}
|
49
|
+
|
50
|
+
// Set the children vector. Prefilter takes ownership of subs and
|
51
|
+
// subs_ will be deleted when Prefilter is deleted.
|
52
|
+
void set_subs(std::vector<Prefilter*>* subs) { subs_ = subs; }
|
53
|
+
|
54
|
+
// Given a RE2, return a Prefilter. The caller takes ownership of
|
55
|
+
// the Prefilter and should deallocate it. Returns NULL if Prefilter
|
56
|
+
// cannot be formed.
|
57
|
+
static Prefilter* FromRE2(const RE2* re2);
|
58
|
+
|
59
|
+
// Returns a readable debug string of the prefilter.
|
60
|
+
std::string DebugString() const;
|
61
|
+
|
62
|
+
private:
|
63
|
+
class Info;
|
64
|
+
|
65
|
+
// Combines two prefilters together to create an AND. The passed
|
66
|
+
// Prefilters will be part of the returned Prefilter or deleted.
|
67
|
+
static Prefilter* And(Prefilter* a, Prefilter* b);
|
68
|
+
|
69
|
+
// Combines two prefilters together to create an OR. The passed
|
70
|
+
// Prefilters will be part of the returned Prefilter or deleted.
|
71
|
+
static Prefilter* Or(Prefilter* a, Prefilter* b);
|
72
|
+
|
73
|
+
// Generalized And/Or
|
74
|
+
static Prefilter* AndOr(Op op, Prefilter* a, Prefilter* b);
|
75
|
+
|
76
|
+
static Prefilter* FromRegexp(Regexp* a);
|
77
|
+
|
78
|
+
static Prefilter* FromString(const std::string& str);
|
79
|
+
|
80
|
+
static Prefilter* OrStrings(std::set<std::string>* ss);
|
81
|
+
|
82
|
+
static Info* BuildInfo(Regexp* re);
|
83
|
+
|
84
|
+
Prefilter* Simplify();
|
85
|
+
|
86
|
+
// Kind of Prefilter.
|
87
|
+
Op op_;
|
88
|
+
|
89
|
+
// Sub-matches for AND or OR Prefilter.
|
90
|
+
std::vector<Prefilter*>* subs_;
|
91
|
+
|
92
|
+
// Actual string to match in leaf node.
|
93
|
+
std::string atom_;
|
94
|
+
|
95
|
+
// If different prefilters have the same string atom, or if they are
|
96
|
+
// structurally the same (e.g., OR of same atom strings) they are
|
97
|
+
// considered the same unique nodes. This is the id for each unique
|
98
|
+
// node. This field is populated with a unique id for every node,
|
99
|
+
// and -1 for duplicate nodes.
|
100
|
+
int unique_id_;
|
101
|
+
|
102
|
+
Prefilter(const Prefilter&) = delete;
|
103
|
+
Prefilter& operator=(const Prefilter&) = delete;
|
104
|
+
};
|
105
|
+
|
106
|
+
} // namespace re2
|
107
|
+
|
108
|
+
#endif // RE2_PREFILTER_H_
|
@@ -0,0 +1,407 @@
|
|
1
|
+
// Copyright 2009 The RE2 Authors. All Rights Reserved.
|
2
|
+
// Use of this source code is governed by a BSD-style
|
3
|
+
// license that can be found in the LICENSE file.
|
4
|
+
|
5
|
+
#include "re2/prefilter_tree.h"
|
6
|
+
|
7
|
+
#include <stddef.h>
|
8
|
+
#include <algorithm>
|
9
|
+
#include <map>
|
10
|
+
#include <memory>
|
11
|
+
#include <set>
|
12
|
+
#include <string>
|
13
|
+
#include <utility>
|
14
|
+
#include <vector>
|
15
|
+
|
16
|
+
#include "util/util.h"
|
17
|
+
#include "util/logging.h"
|
18
|
+
#include "util/strutil.h"
|
19
|
+
#include "re2/prefilter.h"
|
20
|
+
#include "re2/re2.h"
|
21
|
+
|
22
|
+
namespace re2 {
|
23
|
+
|
24
|
+
static const bool ExtraDebug = false;
|
25
|
+
|
26
|
+
PrefilterTree::PrefilterTree()
|
27
|
+
: compiled_(false),
|
28
|
+
min_atom_len_(3) {
|
29
|
+
}
|
30
|
+
|
31
|
+
PrefilterTree::PrefilterTree(int min_atom_len)
|
32
|
+
: compiled_(false),
|
33
|
+
min_atom_len_(min_atom_len) {
|
34
|
+
}
|
35
|
+
|
36
|
+
PrefilterTree::~PrefilterTree() {
|
37
|
+
for (size_t i = 0; i < prefilter_vec_.size(); i++)
|
38
|
+
delete prefilter_vec_[i];
|
39
|
+
|
40
|
+
for (size_t i = 0; i < entries_.size(); i++)
|
41
|
+
delete entries_[i].parents;
|
42
|
+
}
|
43
|
+
|
44
|
+
void PrefilterTree::Add(Prefilter* prefilter) {
|
45
|
+
if (compiled_) {
|
46
|
+
LOG(DFATAL) << "Add called after Compile.";
|
47
|
+
return;
|
48
|
+
}
|
49
|
+
if (prefilter != NULL && !KeepNode(prefilter)) {
|
50
|
+
delete prefilter;
|
51
|
+
prefilter = NULL;
|
52
|
+
}
|
53
|
+
|
54
|
+
prefilter_vec_.push_back(prefilter);
|
55
|
+
}
|
56
|
+
|
57
|
+
void PrefilterTree::Compile(std::vector<std::string>* atom_vec) {
|
58
|
+
if (compiled_) {
|
59
|
+
LOG(DFATAL) << "Compile called already.";
|
60
|
+
return;
|
61
|
+
}
|
62
|
+
|
63
|
+
// Some legacy users of PrefilterTree call Compile() before
|
64
|
+
// adding any regexps and expect Compile() to have no effect.
|
65
|
+
if (prefilter_vec_.empty())
|
66
|
+
return;
|
67
|
+
|
68
|
+
compiled_ = true;
|
69
|
+
|
70
|
+
// TODO(junyer): Use std::unordered_set<Prefilter*> instead?
|
71
|
+
NodeMap nodes;
|
72
|
+
AssignUniqueIds(&nodes, atom_vec);
|
73
|
+
|
74
|
+
// Identify nodes that are too common among prefilters and are
|
75
|
+
// triggering too many parents. Then get rid of them if possible.
|
76
|
+
// Note that getting rid of a prefilter node simply means they are
|
77
|
+
// no longer necessary for their parent to trigger; that is, we do
|
78
|
+
// not miss out on any regexps triggering by getting rid of a
|
79
|
+
// prefilter node.
|
80
|
+
for (size_t i = 0; i < entries_.size(); i++) {
|
81
|
+
StdIntMap* parents = entries_[i].parents;
|
82
|
+
if (parents->size() > 8) {
|
83
|
+
// This one triggers too many things. If all the parents are AND
|
84
|
+
// nodes and have other things guarding them, then get rid of
|
85
|
+
// this trigger. TODO(vsri): Adjust the threshold appropriately,
|
86
|
+
// make it a function of total number of nodes?
|
87
|
+
bool have_other_guard = true;
|
88
|
+
for (StdIntMap::iterator it = parents->begin();
|
89
|
+
it != parents->end(); ++it) {
|
90
|
+
have_other_guard = have_other_guard &&
|
91
|
+
(entries_[it->first].propagate_up_at_count > 1);
|
92
|
+
}
|
93
|
+
|
94
|
+
if (have_other_guard) {
|
95
|
+
for (StdIntMap::iterator it = parents->begin();
|
96
|
+
it != parents->end(); ++it)
|
97
|
+
entries_[it->first].propagate_up_at_count -= 1;
|
98
|
+
|
99
|
+
parents->clear(); // Forget the parents
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
if (ExtraDebug)
|
105
|
+
PrintDebugInfo(&nodes);
|
106
|
+
}
|
107
|
+
|
108
|
+
Prefilter* PrefilterTree::CanonicalNode(NodeMap* nodes, Prefilter* node) {
|
109
|
+
std::string node_string = NodeString(node);
|
110
|
+
NodeMap::iterator iter = nodes->find(node_string);
|
111
|
+
if (iter == nodes->end())
|
112
|
+
return NULL;
|
113
|
+
return (*iter).second;
|
114
|
+
}
|
115
|
+
|
116
|
+
std::string PrefilterTree::NodeString(Prefilter* node) const {
|
117
|
+
// Adding the operation disambiguates AND/OR/atom nodes.
|
118
|
+
std::string s = StringPrintf("%d", node->op()) + ":";
|
119
|
+
if (node->op() == Prefilter::ATOM) {
|
120
|
+
s += node->atom();
|
121
|
+
} else {
|
122
|
+
for (size_t i = 0; i < node->subs()->size(); i++) {
|
123
|
+
if (i > 0)
|
124
|
+
s += ',';
|
125
|
+
s += StringPrintf("%d", (*node->subs())[i]->unique_id());
|
126
|
+
}
|
127
|
+
}
|
128
|
+
return s;
|
129
|
+
}
|
130
|
+
|
131
|
+
bool PrefilterTree::KeepNode(Prefilter* node) const {
|
132
|
+
if (node == NULL)
|
133
|
+
return false;
|
134
|
+
|
135
|
+
switch (node->op()) {
|
136
|
+
default:
|
137
|
+
LOG(DFATAL) << "Unexpected op in KeepNode: " << node->op();
|
138
|
+
return false;
|
139
|
+
|
140
|
+
case Prefilter::ALL:
|
141
|
+
case Prefilter::NONE:
|
142
|
+
return false;
|
143
|
+
|
144
|
+
case Prefilter::ATOM:
|
145
|
+
return node->atom().size() >= static_cast<size_t>(min_atom_len_);
|
146
|
+
|
147
|
+
case Prefilter::AND: {
|
148
|
+
int j = 0;
|
149
|
+
std::vector<Prefilter*>* subs = node->subs();
|
150
|
+
for (size_t i = 0; i < subs->size(); i++)
|
151
|
+
if (KeepNode((*subs)[i]))
|
152
|
+
(*subs)[j++] = (*subs)[i];
|
153
|
+
else
|
154
|
+
delete (*subs)[i];
|
155
|
+
|
156
|
+
subs->resize(j);
|
157
|
+
return j > 0;
|
158
|
+
}
|
159
|
+
|
160
|
+
case Prefilter::OR:
|
161
|
+
for (size_t i = 0; i < node->subs()->size(); i++)
|
162
|
+
if (!KeepNode((*node->subs())[i]))
|
163
|
+
return false;
|
164
|
+
return true;
|
165
|
+
}
|
166
|
+
}
|
167
|
+
|
168
|
+
void PrefilterTree::AssignUniqueIds(NodeMap* nodes,
|
169
|
+
std::vector<std::string>* atom_vec) {
|
170
|
+
atom_vec->clear();
|
171
|
+
|
172
|
+
// Build vector of all filter nodes, sorted topologically
|
173
|
+
// from top to bottom in v.
|
174
|
+
std::vector<Prefilter*> v;
|
175
|
+
|
176
|
+
// Add the top level nodes of each regexp prefilter.
|
177
|
+
for (size_t i = 0; i < prefilter_vec_.size(); i++) {
|
178
|
+
Prefilter* f = prefilter_vec_[i];
|
179
|
+
if (f == NULL)
|
180
|
+
unfiltered_.push_back(static_cast<int>(i));
|
181
|
+
|
182
|
+
// We push NULL also on to v, so that we maintain the
|
183
|
+
// mapping of index==regexpid for level=0 prefilter nodes.
|
184
|
+
v.push_back(f);
|
185
|
+
}
|
186
|
+
|
187
|
+
// Now add all the descendant nodes.
|
188
|
+
for (size_t i = 0; i < v.size(); i++) {
|
189
|
+
Prefilter* f = v[i];
|
190
|
+
if (f == NULL)
|
191
|
+
continue;
|
192
|
+
if (f->op() == Prefilter::AND || f->op() == Prefilter::OR) {
|
193
|
+
const std::vector<Prefilter*>& subs = *f->subs();
|
194
|
+
for (size_t j = 0; j < subs.size(); j++)
|
195
|
+
v.push_back(subs[j]);
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
// Identify unique nodes.
|
200
|
+
int unique_id = 0;
|
201
|
+
for (int i = static_cast<int>(v.size()) - 1; i >= 0; i--) {
|
202
|
+
Prefilter *node = v[i];
|
203
|
+
if (node == NULL)
|
204
|
+
continue;
|
205
|
+
node->set_unique_id(-1);
|
206
|
+
Prefilter* canonical = CanonicalNode(nodes, node);
|
207
|
+
if (canonical == NULL) {
|
208
|
+
// Any further nodes that have the same node string
|
209
|
+
// will find this node as the canonical node.
|
210
|
+
nodes->emplace(NodeString(node), node);
|
211
|
+
if (node->op() == Prefilter::ATOM) {
|
212
|
+
atom_vec->push_back(node->atom());
|
213
|
+
atom_index_to_id_.push_back(unique_id);
|
214
|
+
}
|
215
|
+
node->set_unique_id(unique_id++);
|
216
|
+
} else {
|
217
|
+
node->set_unique_id(canonical->unique_id());
|
218
|
+
}
|
219
|
+
}
|
220
|
+
entries_.resize(nodes->size());
|
221
|
+
|
222
|
+
// Create parent StdIntMap for the entries.
|
223
|
+
for (int i = static_cast<int>(v.size()) - 1; i >= 0; i--) {
|
224
|
+
Prefilter* prefilter = v[i];
|
225
|
+
if (prefilter == NULL)
|
226
|
+
continue;
|
227
|
+
|
228
|
+
if (CanonicalNode(nodes, prefilter) != prefilter)
|
229
|
+
continue;
|
230
|
+
|
231
|
+
Entry* entry = &entries_[prefilter->unique_id()];
|
232
|
+
entry->parents = new StdIntMap();
|
233
|
+
}
|
234
|
+
|
235
|
+
// Fill the entries.
|
236
|
+
for (int i = static_cast<int>(v.size()) - 1; i >= 0; i--) {
|
237
|
+
Prefilter* prefilter = v[i];
|
238
|
+
if (prefilter == NULL)
|
239
|
+
continue;
|
240
|
+
|
241
|
+
if (CanonicalNode(nodes, prefilter) != prefilter)
|
242
|
+
continue;
|
243
|
+
|
244
|
+
Entry* entry = &entries_[prefilter->unique_id()];
|
245
|
+
|
246
|
+
switch (prefilter->op()) {
|
247
|
+
default:
|
248
|
+
case Prefilter::ALL:
|
249
|
+
LOG(DFATAL) << "Unexpected op: " << prefilter->op();
|
250
|
+
return;
|
251
|
+
|
252
|
+
case Prefilter::ATOM:
|
253
|
+
entry->propagate_up_at_count = 1;
|
254
|
+
break;
|
255
|
+
|
256
|
+
case Prefilter::OR:
|
257
|
+
case Prefilter::AND: {
|
258
|
+
std::set<int> uniq_child;
|
259
|
+
for (size_t j = 0; j < prefilter->subs()->size(); j++) {
|
260
|
+
Prefilter* child = (*prefilter->subs())[j];
|
261
|
+
Prefilter* canonical = CanonicalNode(nodes, child);
|
262
|
+
if (canonical == NULL) {
|
263
|
+
LOG(DFATAL) << "Null canonical node";
|
264
|
+
return;
|
265
|
+
}
|
266
|
+
int child_id = canonical->unique_id();
|
267
|
+
uniq_child.insert(child_id);
|
268
|
+
// To the child, we want to add to parent indices.
|
269
|
+
Entry* child_entry = &entries_[child_id];
|
270
|
+
if (child_entry->parents->find(prefilter->unique_id()) ==
|
271
|
+
child_entry->parents->end()) {
|
272
|
+
(*child_entry->parents)[prefilter->unique_id()] = 1;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
entry->propagate_up_at_count = prefilter->op() == Prefilter::AND
|
276
|
+
? static_cast<int>(uniq_child.size())
|
277
|
+
: 1;
|
278
|
+
|
279
|
+
break;
|
280
|
+
}
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
// For top level nodes, populate regexp id.
|
285
|
+
for (size_t i = 0; i < prefilter_vec_.size(); i++) {
|
286
|
+
if (prefilter_vec_[i] == NULL)
|
287
|
+
continue;
|
288
|
+
int id = CanonicalNode(nodes, prefilter_vec_[i])->unique_id();
|
289
|
+
DCHECK_LE(0, id);
|
290
|
+
Entry* entry = &entries_[id];
|
291
|
+
entry->regexps.push_back(static_cast<int>(i));
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
// Functions for triggering during search.
|
296
|
+
void PrefilterTree::RegexpsGivenStrings(
|
297
|
+
const std::vector<int>& matched_atoms,
|
298
|
+
std::vector<int>* regexps) const {
|
299
|
+
regexps->clear();
|
300
|
+
if (!compiled_) {
|
301
|
+
// Some legacy users of PrefilterTree call Compile() before
|
302
|
+
// adding any regexps and expect Compile() to have no effect.
|
303
|
+
// This kludge is a counterpart to that kludge.
|
304
|
+
if (prefilter_vec_.empty())
|
305
|
+
return;
|
306
|
+
|
307
|
+
LOG(ERROR) << "RegexpsGivenStrings called before Compile.";
|
308
|
+
for (size_t i = 0; i < prefilter_vec_.size(); i++)
|
309
|
+
regexps->push_back(static_cast<int>(i));
|
310
|
+
} else {
|
311
|
+
IntMap regexps_map(static_cast<int>(prefilter_vec_.size()));
|
312
|
+
std::vector<int> matched_atom_ids;
|
313
|
+
for (size_t j = 0; j < matched_atoms.size(); j++)
|
314
|
+
matched_atom_ids.push_back(atom_index_to_id_[matched_atoms[j]]);
|
315
|
+
PropagateMatch(matched_atom_ids, ®exps_map);
|
316
|
+
for (IntMap::iterator it = regexps_map.begin();
|
317
|
+
it != regexps_map.end();
|
318
|
+
++it)
|
319
|
+
regexps->push_back(it->index());
|
320
|
+
|
321
|
+
regexps->insert(regexps->end(), unfiltered_.begin(), unfiltered_.end());
|
322
|
+
}
|
323
|
+
std::sort(regexps->begin(), regexps->end());
|
324
|
+
}
|
325
|
+
|
326
|
+
void PrefilterTree::PropagateMatch(const std::vector<int>& atom_ids,
|
327
|
+
IntMap* regexps) const {
|
328
|
+
IntMap count(static_cast<int>(entries_.size()));
|
329
|
+
IntMap work(static_cast<int>(entries_.size()));
|
330
|
+
for (size_t i = 0; i < atom_ids.size(); i++)
|
331
|
+
work.set(atom_ids[i], 1);
|
332
|
+
for (IntMap::iterator it = work.begin(); it != work.end(); ++it) {
|
333
|
+
const Entry& entry = entries_[it->index()];
|
334
|
+
// Record regexps triggered.
|
335
|
+
for (size_t i = 0; i < entry.regexps.size(); i++)
|
336
|
+
regexps->set(entry.regexps[i], 1);
|
337
|
+
int c;
|
338
|
+
// Pass trigger up to parents.
|
339
|
+
for (StdIntMap::iterator it = entry.parents->begin();
|
340
|
+
it != entry.parents->end();
|
341
|
+
++it) {
|
342
|
+
int j = it->first;
|
343
|
+
const Entry& parent = entries_[j];
|
344
|
+
// Delay until all the children have succeeded.
|
345
|
+
if (parent.propagate_up_at_count > 1) {
|
346
|
+
if (count.has_index(j)) {
|
347
|
+
c = count.get_existing(j) + 1;
|
348
|
+
count.set_existing(j, c);
|
349
|
+
} else {
|
350
|
+
c = 1;
|
351
|
+
count.set_new(j, c);
|
352
|
+
}
|
353
|
+
if (c < parent.propagate_up_at_count)
|
354
|
+
continue;
|
355
|
+
}
|
356
|
+
// Trigger the parent.
|
357
|
+
work.set(j, 1);
|
358
|
+
}
|
359
|
+
}
|
360
|
+
}
|
361
|
+
|
362
|
+
// Debugging help.
|
363
|
+
void PrefilterTree::PrintPrefilter(int regexpid) {
|
364
|
+
LOG(ERROR) << DebugNodeString(prefilter_vec_[regexpid]);
|
365
|
+
}
|
366
|
+
|
367
|
+
void PrefilterTree::PrintDebugInfo(NodeMap* nodes) {
|
368
|
+
LOG(ERROR) << "#Unique Atoms: " << atom_index_to_id_.size();
|
369
|
+
LOG(ERROR) << "#Unique Nodes: " << entries_.size();
|
370
|
+
|
371
|
+
for (size_t i = 0; i < entries_.size(); i++) {
|
372
|
+
StdIntMap* parents = entries_[i].parents;
|
373
|
+
const std::vector<int>& regexps = entries_[i].regexps;
|
374
|
+
LOG(ERROR) << "EntryId: " << i
|
375
|
+
<< " N: " << parents->size() << " R: " << regexps.size();
|
376
|
+
for (StdIntMap::iterator it = parents->begin(); it != parents->end(); ++it)
|
377
|
+
LOG(ERROR) << it->first;
|
378
|
+
}
|
379
|
+
LOG(ERROR) << "Map:";
|
380
|
+
for (NodeMap::const_iterator iter = nodes->begin();
|
381
|
+
iter != nodes->end(); ++iter)
|
382
|
+
LOG(ERROR) << "NodeId: " << (*iter).second->unique_id()
|
383
|
+
<< " Str: " << (*iter).first;
|
384
|
+
}
|
385
|
+
|
386
|
+
std::string PrefilterTree::DebugNodeString(Prefilter* node) const {
|
387
|
+
std::string node_string = "";
|
388
|
+
if (node->op() == Prefilter::ATOM) {
|
389
|
+
DCHECK(!node->atom().empty());
|
390
|
+
node_string += node->atom();
|
391
|
+
} else {
|
392
|
+
// Adding the operation disambiguates AND and OR nodes.
|
393
|
+
node_string += node->op() == Prefilter::AND ? "AND" : "OR";
|
394
|
+
node_string += "(";
|
395
|
+
for (size_t i = 0; i < node->subs()->size(); i++) {
|
396
|
+
if (i > 0)
|
397
|
+
node_string += ',';
|
398
|
+
node_string += StringPrintf("%d", (*node->subs())[i]->unique_id());
|
399
|
+
node_string += ":";
|
400
|
+
node_string += DebugNodeString((*node->subs())[i]);
|
401
|
+
}
|
402
|
+
node_string += ")";
|
403
|
+
}
|
404
|
+
return node_string;
|
405
|
+
}
|
406
|
+
|
407
|
+
} // namespace re2
|