re2 1.19.2 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/.github/actions/linux-alpine-node-16/Dockerfile +1 -1
  2. package/.github/actions/linux-alpine-node-18/Dockerfile +1 -1
  3. package/.github/actions/linux-alpine-node-20/Dockerfile +1 -1
  4. package/.gitmodules +5 -2
  5. package/README.md +1 -0
  6. package/binding.gyp +82 -25
  7. package/lib/replace.cc +4 -4
  8. package/package.json +1 -1
  9. package/tsconfig.json +2 -1
  10. package/vendor/re2/.bazelrc +16 -0
  11. package/vendor/re2/.github/bazel.sh +24 -0
  12. package/vendor/re2/.github/cmake.sh +12 -0
  13. package/vendor/re2/.github/workflows/ci-bazel.yml +17 -0
  14. package/vendor/re2/.github/workflows/ci-cmake.yml +108 -0
  15. package/vendor/re2/.github/workflows/ci.yml +89 -0
  16. package/vendor/re2/.github/workflows/pr.yml +26 -0
  17. package/vendor/re2/.github/workflows/python.yml +185 -0
  18. package/vendor/re2/AUTHORS +13 -0
  19. package/vendor/re2/BUILD.bazel +280 -0
  20. package/vendor/re2/CMakeLists.txt +268 -0
  21. package/vendor/re2/CONTRIBUTING.md +2 -0
  22. package/vendor/re2/CONTRIBUTORS +41 -0
  23. package/vendor/re2/Makefile +400 -0
  24. package/vendor/{README → re2/README} +5 -0
  25. package/vendor/re2/SECURITY.md +4 -0
  26. package/vendor/re2/WORKSPACE.bazel +62 -0
  27. package/vendor/re2/app/BUILD.bazel +19 -0
  28. package/vendor/re2/app/_re2.cc +94 -0
  29. package/vendor/re2/app/_re2.d.ts +23 -0
  30. package/vendor/re2/app/app.ts +111 -0
  31. package/vendor/re2/app/build.sh +50 -0
  32. package/vendor/re2/app/index.html +5 -0
  33. package/vendor/re2/app/package.json +14 -0
  34. package/vendor/re2/app/rollup.config.js +28 -0
  35. package/vendor/re2/app/tsconfig.json +17 -0
  36. package/vendor/re2/benchlog/benchplot.py +98 -0
  37. package/vendor/re2/benchlog/mktable +155 -0
  38. package/vendor/re2/doc/mksyntaxgo +42 -0
  39. package/vendor/re2/doc/mksyntaxhtml +42 -0
  40. package/vendor/re2/doc/mksyntaxwiki +36 -0
  41. package/vendor/re2/doc/syntax.html +477 -0
  42. package/vendor/re2/doc/syntax.txt +463 -0
  43. package/vendor/re2/lib/git/commit-msg.hook +104 -0
  44. package/vendor/re2/libre2.symbols +19 -0
  45. package/vendor/re2/libre2.symbols.darwin +15 -0
  46. package/vendor/re2/python/BUILD.bazel +36 -0
  47. package/vendor/re2/python/README +1 -0
  48. package/vendor/re2/python/_re2.cc +338 -0
  49. package/vendor/re2/python/re2.py +582 -0
  50. package/vendor/re2/python/re2_test.py +482 -0
  51. package/vendor/re2/python/setup.py +105 -0
  52. package/vendor/re2/{bitmap256.cc → re2/bitmap256.cc} +4 -4
  53. package/vendor/re2/{bitstate.cc → re2/bitstate.cc} +21 -25
  54. package/vendor/re2/{compile.cc → re2/compile.cc} +5 -4
  55. package/vendor/re2/{dfa.cc → re2/dfa.cc} +120 -101
  56. package/vendor/re2/{filtered_re2.cc → re2/filtered_re2.cc} +8 -11
  57. package/vendor/re2/{filtered_re2.h → re2/filtered_re2.h} +5 -4
  58. package/vendor/re2/{fuzzing → re2/fuzzing}/re2_fuzzer.cc +4 -6
  59. package/vendor/re2/{mimics_pcre.cc → re2/mimics_pcre.cc} +0 -1
  60. package/vendor/re2/{nfa.cc → re2/nfa.cc} +34 -37
  61. package/vendor/re2/{onepass.cc → re2/onepass.cc} +25 -27
  62. package/vendor/re2/{parse.cc → re2/parse.cc} +118 -121
  63. package/vendor/re2/{prefilter.cc → re2/prefilter.cc} +2 -3
  64. package/vendor/re2/{prefilter.h → re2/prefilter.h} +0 -1
  65. package/vendor/re2/{prefilter_tree.cc → re2/prefilter_tree.cc} +4 -5
  66. package/vendor/re2/{prefilter_tree.h → re2/prefilter_tree.h} +1 -2
  67. package/vendor/re2/{prog.cc → re2/prog.cc} +20 -21
  68. package/vendor/re2/{prog.h → re2/prog.h} +21 -22
  69. package/vendor/re2/{re2.cc → re2/re2.cc} +51 -62
  70. package/vendor/re2/{re2.h → re2/re2.h} +78 -40
  71. package/vendor/re2/{regexp.cc → re2/regexp.cc} +11 -12
  72. package/vendor/re2/{regexp.h → re2/regexp.h} +9 -10
  73. package/vendor/re2/{set.cc → re2/set.cc} +3 -5
  74. package/vendor/re2/{set.h → re2/set.h} +4 -3
  75. package/vendor/re2/{simplify.cc → re2/simplify.cc} +1 -2
  76. package/vendor/re2/re2/stringpiece.h +24 -0
  77. package/vendor/re2/{testing → re2/testing}/backtrack.cc +22 -25
  78. package/vendor/re2/{testing → re2/testing}/charclass_test.cc +23 -21
  79. package/vendor/re2/{testing → re2/testing}/compile_test.cc +5 -4
  80. package/vendor/re2/{testing → re2/testing}/dfa_test.cc +36 -30
  81. package/vendor/re2/{testing → re2/testing}/dump.cc +8 -8
  82. package/vendor/re2/{testing → re2/testing}/exhaustive1_test.cc +1 -1
  83. package/vendor/re2/{testing → re2/testing}/exhaustive2_test.cc +1 -1
  84. package/vendor/re2/{testing → re2/testing}/exhaustive3_test.cc +1 -1
  85. package/vendor/re2/{testing → re2/testing}/exhaustive_test.cc +1 -1
  86. package/vendor/re2/{testing → re2/testing}/exhaustive_tester.cc +36 -32
  87. package/vendor/re2/{testing → re2/testing}/exhaustive_tester.h +0 -1
  88. package/vendor/re2/{testing → re2/testing}/filtered_re2_test.cc +9 -8
  89. package/vendor/re2/{testing → re2/testing}/mimics_pcre_test.cc +3 -2
  90. package/vendor/re2/{testing → re2/testing}/null_walker.cc +1 -1
  91. package/vendor/re2/{testing → re2/testing}/parse_test.cc +13 -12
  92. package/vendor/re2/{testing → re2/testing}/possible_match_test.cc +15 -14
  93. package/vendor/re2/{testing → re2/testing}/random_test.cc +13 -12
  94. package/vendor/re2/{testing → re2/testing}/re2_arg_test.cc +25 -2
  95. package/vendor/re2/{testing → re2/testing}/re2_test.cc +49 -47
  96. package/vendor/re2/{testing → re2/testing}/regexp_benchmark.cc +144 -145
  97. package/vendor/re2/{testing → re2/testing}/regexp_generator.cc +18 -14
  98. package/vendor/re2/{testing → re2/testing}/regexp_generator.h +3 -4
  99. package/vendor/re2/{testing → re2/testing}/regexp_test.cc +1 -1
  100. package/vendor/re2/{testing → re2/testing}/required_prefix_test.cc +5 -4
  101. package/vendor/re2/{testing → re2/testing}/search_test.cc +3 -2
  102. package/vendor/re2/{testing → re2/testing}/set_test.cc +1 -1
  103. package/vendor/re2/{testing → re2/testing}/simplify_test.cc +3 -2
  104. package/vendor/re2/{testing → re2/testing}/string_generator.cc +3 -3
  105. package/vendor/re2/{testing → re2/testing}/string_generator.h +5 -6
  106. package/vendor/re2/{testing → re2/testing}/string_generator_test.cc +2 -2
  107. package/vendor/re2/{testing → re2/testing}/tester.cc +77 -78
  108. package/vendor/re2/{testing → re2/testing}/tester.h +13 -15
  109. package/vendor/re2/{tostring.cc → re2/tostring.cc} +7 -8
  110. package/vendor/re2/{unicode_casefold.h → re2/unicode_casefold.h} +0 -1
  111. package/vendor/re2/{unicode_groups.h → re2/unicode_groups.h} +0 -1
  112. package/vendor/re2/{walker-inl.h → re2/walker-inl.h} +2 -1
  113. package/vendor/re2/re2.pc.in +9 -0
  114. package/vendor/re2/re2Config.cmake.in +28 -0
  115. package/vendor/re2/runtests +33 -0
  116. package/vendor/re2/testinstall.cc +27 -0
  117. package/vendor/re2/ucs2.diff +567 -0
  118. package/vendor/{util → re2/util}/logging.h +2 -2
  119. package/vendor/{util → re2/util}/pcre.cc +47 -116
  120. package/vendor/{util → re2/util}/pcre.h +53 -63
  121. package/vendor/re2/util/strutil.cc +26 -0
  122. package/vendor/{util → re2/util}/strutil.h +0 -5
  123. package/vendor/re2/stringpiece.cc +0 -65
  124. package/vendor/re2/stringpiece.h +0 -213
  125. package/vendor/util/benchmark.cc +0 -131
  126. package/vendor/util/benchmark.h +0 -156
  127. package/vendor/util/flags.h +0 -26
  128. package/vendor/util/mix.h +0 -41
  129. package/vendor/util/mutex.h +0 -164
  130. package/vendor/util/strutil.cc +0 -149
  131. package/vendor/util/test.cc +0 -34
  132. package/vendor/util/test.h +0 -50
  133. package/vendor/util/util.h +0 -42
  134. /package/vendor/{LICENSE → re2/LICENSE} +0 -0
  135. /package/vendor/re2/{bitmap256.h → re2/bitmap256.h} +0 -0
  136. /package/vendor/re2/{fuzzing → re2/fuzzing}/compiler-rt/LICENSE +0 -0
  137. /package/vendor/re2/{fuzzing → re2/fuzzing}/compiler-rt/include/fuzzer/FuzzedDataProvider.h +0 -0
  138. /package/vendor/re2/{make_perl_groups.pl → re2/make_perl_groups.pl} +0 -0
  139. /package/vendor/re2/{make_unicode_casefold.py → re2/make_unicode_casefold.py} +0 -0
  140. /package/vendor/re2/{make_unicode_groups.py → re2/make_unicode_groups.py} +0 -0
  141. /package/vendor/re2/{perl_groups.cc → re2/perl_groups.cc} +0 -0
  142. /package/vendor/re2/{pod_array.h → re2/pod_array.h} +0 -0
  143. /package/vendor/re2/{sparse_array.h → re2/sparse_array.h} +0 -0
  144. /package/vendor/re2/{sparse_set.h → re2/sparse_set.h} +0 -0
  145. /package/vendor/re2/{unicode.py → re2/unicode.py} +0 -0
  146. /package/vendor/re2/{unicode_casefold.cc → re2/unicode_casefold.cc} +0 -0
  147. /package/vendor/re2/{unicode_groups.cc → re2/unicode_groups.cc} +0 -0
  148. /package/vendor/{util → re2/util}/fuzz.cc +0 -0
  149. /package/vendor/{util → re2/util}/malloc_counter.h +0 -0
  150. /package/vendor/{util → re2/util}/rune.cc +0 -0
  151. /package/vendor/{util → re2/util}/utf.h +0 -0
@@ -28,23 +28,25 @@
28
28
  #include <algorithm>
29
29
  #include <atomic>
30
30
  #include <deque>
31
- #include <mutex>
32
31
  #include <new>
33
32
  #include <string>
34
- #include <unordered_map>
35
- #include <unordered_set>
36
33
  #include <utility>
37
34
  #include <vector>
38
35
 
36
+ #include "absl/base/call_once.h"
37
+ #include "absl/base/macros.h"
38
+ #include "absl/base/thread_annotations.h"
39
+ #include "absl/container/flat_hash_map.h"
40
+ #include "absl/container/flat_hash_set.h"
41
+ #include "absl/strings/str_format.h"
42
+ #include "absl/synchronization/mutex.h"
43
+ #include "absl/types/span.h"
39
44
  #include "util/logging.h"
40
- #include "util/mix.h"
41
- #include "util/mutex.h"
42
45
  #include "util/strutil.h"
43
46
  #include "re2/pod_array.h"
44
47
  #include "re2/prog.h"
45
48
  #include "re2/re2.h"
46
49
  #include "re2/sparse_set.h"
47
- #include "re2/stringpiece.h"
48
50
 
49
51
  // Silence "zero-sized array in struct/union" warning for DFA::State::next_.
50
52
  #ifdef _MSC_VER
@@ -88,9 +90,9 @@ class DFA {
88
90
  // returning the leftmost end of the match instead of the rightmost one.
89
91
  // If the DFA cannot complete the search (for example, if it is out of
90
92
  // memory), it sets *failed and returns false.
91
- bool Search(const StringPiece& text, const StringPiece& context,
92
- bool anchored, bool want_earliest_match, bool run_forward,
93
- bool* failed, const char** ep, SparseSet* matches);
93
+ bool Search(absl::string_view text, absl::string_view context, bool anchored,
94
+ bool want_earliest_match, bool run_forward, bool* failed,
95
+ const char** ep, SparseSet* matches);
94
96
 
95
97
  // Builds out all states for the entire DFA.
96
98
  // If cb is not empty, it receives one callback per state built.
@@ -114,6 +116,18 @@ class DFA {
114
116
  struct State {
115
117
  inline bool IsMatch() const { return (flag_ & kFlagMatch) != 0; }
116
118
 
119
+ template <typename H>
120
+ friend H AbslHashValue(H h, const State& a) {
121
+ const absl::Span<const int> ainst(a.inst_, a.ninst_);
122
+ return H::combine(std::move(h), a.flag_, ainst);
123
+ }
124
+
125
+ friend bool operator==(const State& a, const State& b) {
126
+ const absl::Span<const int> ainst(a.inst_, a.ninst_);
127
+ const absl::Span<const int> binst(b.inst_, b.ninst_);
128
+ return &a == &b || (a.flag_ == b.flag_ && ainst == binst);
129
+ }
130
+
117
131
  int* inst_; // Instruction pointers in the state.
118
132
  int ninst_; // # of inst_ pointers.
119
133
  uint32_t flag_; // Empty string bitfield flags in effect on the way
@@ -124,11 +138,11 @@ class DFA {
124
138
  // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70932)
125
139
  #if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 6 && __GNUC_MINOR__ >= 1
126
140
  std::atomic<State*> next_[0]; // Outgoing arrows from State,
141
+ // one per input byte class
127
142
  #else
128
143
  std::atomic<State*> next_[]; // Outgoing arrows from State,
144
+ // one per input byte class
129
145
  #endif
130
-
131
- // one per input byte class
132
146
  };
133
147
 
134
148
  enum {
@@ -143,11 +157,7 @@ class DFA {
143
157
  struct StateHash {
144
158
  size_t operator()(const State* a) const {
145
159
  DCHECK(a != NULL);
146
- HashMix mix(a->flag_);
147
- for (int i = 0; i < a->ninst_; i++)
148
- mix.Mix(a->inst_[i]);
149
- mix.Mix(0);
150
- return mix.get();
160
+ return absl::Hash<State>()(*a);
151
161
  }
152
162
  };
153
163
 
@@ -155,24 +165,15 @@ class DFA {
155
165
  bool operator()(const State* a, const State* b) const {
156
166
  DCHECK(a != NULL);
157
167
  DCHECK(b != NULL);
158
- if (a == b)
159
- return true;
160
- if (a->flag_ != b->flag_)
161
- return false;
162
- if (a->ninst_ != b->ninst_)
163
- return false;
164
- for (int i = 0; i < a->ninst_; i++)
165
- if (a->inst_[i] != b->inst_[i])
166
- return false;
167
- return true;
168
+ return *a == *b;
168
169
  }
169
170
  };
170
171
 
171
- typedef std::unordered_set<State*, StateHash, StateEqual> StateSet;
172
+ typedef absl::flat_hash_set<State*, StateHash, StateEqual> StateSet;
172
173
 
173
174
  private:
174
175
  // Make it easier to swap in a scalable reader-writer mutex.
175
- using CacheMutex = Mutex;
176
+ using CacheMutex = absl::Mutex;
176
177
 
177
178
  enum {
178
179
  // Indices into start_ for unanchored searches.
@@ -238,7 +239,7 @@ class DFA {
238
239
 
239
240
  // Search parameters
240
241
  struct SearchParams {
241
- SearchParams(const StringPiece& text, const StringPiece& context,
242
+ SearchParams(absl::string_view text, absl::string_view context,
242
243
  RWLocker* cache_lock)
243
244
  : text(text),
244
245
  context(context),
@@ -252,8 +253,8 @@ class DFA {
252
253
  ep(NULL),
253
254
  matches(NULL) {}
254
255
 
255
- StringPiece text;
256
- StringPiece context;
256
+ absl::string_view text;
257
+ absl::string_view context;
257
258
  bool anchored;
258
259
  bool can_prefix_accel;
259
260
  bool want_earliest_match;
@@ -325,7 +326,7 @@ class DFA {
325
326
  Prog::MatchKind kind_; // The kind of DFA.
326
327
  bool init_failed_; // initialization failed (out of memory)
327
328
 
328
- Mutex mutex_; // mutex_ >= cache_mutex_.r
329
+ absl::Mutex mutex_; // mutex_ >= cache_mutex_.r
329
330
 
330
331
  // Scratch areas, protected by mutex_.
331
332
  Workq* q0_; // Two pre-allocated work queues.
@@ -428,7 +429,7 @@ DFA::DFA(Prog* prog, Prog::MatchKind kind, int64_t max_mem)
428
429
  q1_(NULL),
429
430
  mem_budget_(max_mem) {
430
431
  if (ExtraDebug)
431
- fprintf(stderr, "\nkind %d\n%s\n", kind_, prog_->DumpUnanchored().c_str());
432
+ absl::FPrintF(stderr, "\nkind %d\n%s\n", kind_, prog_->DumpUnanchored());
432
433
  int nmark = 0;
433
434
  if (kind_ == Prog::kLongestMatch)
434
435
  nmark = prog_->size();
@@ -498,7 +499,7 @@ std::string DFA::DumpWorkq(Workq* q) {
498
499
  s += "|";
499
500
  sep = "";
500
501
  } else {
501
- s += StringPrintf("%s%d", sep, *it);
502
+ s += absl::StrFormat("%s%d", sep, *it);
502
503
  sep = ",";
503
504
  }
504
505
  }
@@ -515,7 +516,7 @@ std::string DFA::DumpState(State* state) {
515
516
  return "*";
516
517
  std::string s;
517
518
  const char* sep = "";
518
- s += StringPrintf("(%p)", state);
519
+ s += absl::StrFormat("(%p)", state);
519
520
  for (int i = 0; i < state->ninst_; i++) {
520
521
  if (state->inst_[i] == Mark) {
521
522
  s += "|";
@@ -524,11 +525,11 @@ std::string DFA::DumpState(State* state) {
524
525
  s += "||";
525
526
  sep = "";
526
527
  } else {
527
- s += StringPrintf("%s%d", sep, state->inst_[i]);
528
+ s += absl::StrFormat("%s%d", sep, state->inst_[i]);
528
529
  sep = ",";
529
530
  }
530
531
  }
531
- s += StringPrintf(" flag=%#x", state->flag_);
532
+ s += absl::StrFormat(" flag=%#x", state->flag_);
532
533
  return s;
533
534
  }
534
535
 
@@ -596,16 +597,35 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) {
596
597
  //mutex_.AssertHeld();
597
598
 
598
599
  // Construct array of instruction ids for the new state.
599
- // Only ByteRange, EmptyWidth, and Match instructions are useful to keep:
600
- // those are the only operators with any effect in
601
- // RunWorkqOnEmptyString or RunWorkqOnByte.
600
+ // In some cases, kInstAltMatch may trigger an upgrade to FullMatchState.
601
+ // Otherwise, "compress" q down to list heads for storage; StateToWorkq()
602
+ // will "decompress" it for computation by exploring from each list head.
603
+ //
604
+ // Historically, only kInstByteRange, kInstEmptyWidth and kInstMatch were
605
+ // useful to keep, but it turned out that kInstAlt was necessary to keep:
606
+ //
607
+ // > [*] kInstAlt would seem useless to record in a state, since
608
+ // > we've already followed both its arrows and saved all the
609
+ // > interesting states we can reach from there. The problem
610
+ // > is that one of the empty-width instructions might lead
611
+ // > back to the same kInstAlt (if an empty-width operator is starred),
612
+ // > producing a different evaluation order depending on whether
613
+ // > we keep the kInstAlt to begin with. Sigh.
614
+ // > A specific case that this affects is /(^|a)+/ matching "a".
615
+ // > If we don't save the kInstAlt, we will match the whole "a" (0,1)
616
+ // > but in fact the correct leftmost-first match is the leading "" (0,0).
617
+ //
618
+ // Recall that flattening transformed the Prog from "tree" form to "list"
619
+ // form: in the former, kInstAlt existed explicitly... and abundantly; in
620
+ // the latter, it's implied between the instructions that compose a list.
621
+ // Thus, because the information wasn't lost, the bug doesn't remanifest.
602
622
  PODArray<int> inst(q->size());
603
623
  int n = 0;
604
624
  uint32_t needflags = 0; // flags needed by kInstEmptyWidth instructions
605
625
  bool sawmatch = false; // whether queue contains guaranteed kInstMatch
606
626
  bool sawmark = false; // whether queue contains a Mark
607
627
  if (ExtraDebug)
608
- fprintf(stderr, "WorkqToCachedState %s [%#x]", DumpWorkq(q).c_str(), flag);
628
+ absl::FPrintF(stderr, "WorkqToCachedState %s [%#x]", DumpWorkq(q), flag);
609
629
  for (Workq::iterator it = q->begin(); it != q->end(); ++it) {
610
630
  int id = *it;
611
631
  if (sawmatch && (kind_ == Prog::kFirstMatch || q->is_mark(id)))
@@ -630,10 +650,10 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) {
630
650
  (kind_ != Prog::kLongestMatch || !sawmark) &&
631
651
  (flag & kFlagMatch)) {
632
652
  if (ExtraDebug)
633
- fprintf(stderr, " -> FullMatchState\n");
653
+ absl::FPrintF(stderr, " -> FullMatchState\n");
634
654
  return FullMatchState;
635
655
  }
636
- FALLTHROUGH_INTENDED;
656
+ ABSL_FALLTHROUGH_INTENDED;
637
657
  default:
638
658
  // Record iff id is the head of its list, which must
639
659
  // be the case if id-1 is the last of *its* list. :)
@@ -676,7 +696,7 @@ DFA::State* DFA::WorkqToCachedState(Workq* q, Workq* mq, uint32_t flag) {
676
696
  // if the state is *not* a matching state.
677
697
  if (n == 0 && flag == 0) {
678
698
  if (ExtraDebug)
679
- fprintf(stderr, " -> DeadState\n");
699
+ absl::FPrintF(stderr, " -> DeadState\n");
680
700
  return DeadState;
681
701
  }
682
702
 
@@ -740,25 +760,29 @@ DFA::State* DFA::CachedState(int* inst, int ninst, uint32_t flag) {
740
760
  StateSet::iterator it = state_cache_.find(&state);
741
761
  if (it != state_cache_.end()) {
742
762
  if (ExtraDebug)
743
- fprintf(stderr, " -cached-> %s\n", DumpState(*it).c_str());
763
+ absl::FPrintF(stderr, " -cached-> %s\n", DumpState(*it));
744
764
  return *it;
745
765
  }
746
766
 
747
767
  // Must have enough memory for new state.
748
768
  // In addition to what we're going to allocate,
749
- // the state cache hash table seems to incur about 40 bytes per
750
- // State*, empirically.
751
- const int kStateCacheOverhead = 40;
769
+ // the state cache hash table seems to incur about 18 bytes per
770
+ // State*. Worst case for non-small sets is it being half full, where each
771
+ // value present takes up 1 byte hash sample plus the pointer itself.
772
+ const int kStateCacheOverhead = 18;
752
773
  int nnext = prog_->bytemap_range() + 1; // + 1 for kByteEndText slot
753
- int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>) +
754
- ninst*sizeof(int);
755
- if (mem_budget_ < mem + kStateCacheOverhead) {
774
+ int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>);
775
+ int instmem = ninst*sizeof(int);
776
+ if (mem_budget_ < mem + instmem + kStateCacheOverhead) {
756
777
  mem_budget_ = -1;
757
778
  return NULL;
758
779
  }
759
- mem_budget_ -= mem + kStateCacheOverhead;
780
+ mem_budget_ -= mem + instmem + kStateCacheOverhead;
760
781
 
761
782
  // Allocate new state along with room for next_ and inst_.
783
+ // inst_ is stored separately since it's colder; this also
784
+ // means that the States for a given DFA are the same size
785
+ // class, so the allocator can hopefully pack them better.
762
786
  char* space = std::allocator<char>().allocate(mem);
763
787
  State* s = new (space) State;
764
788
  (void) new (s->next_) std::atomic<State*>[nnext];
@@ -766,12 +790,13 @@ DFA::State* DFA::CachedState(int* inst, int ninst, uint32_t flag) {
766
790
  // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64658)
767
791
  for (int i = 0; i < nnext; i++)
768
792
  (void) new (s->next_ + i) std::atomic<State*>(NULL);
769
- s->inst_ = new (s->next_ + nnext) int[ninst];
770
- memmove(s->inst_, inst, ninst*sizeof s->inst_[0]);
793
+ s->inst_ = std::allocator<int>().allocate(ninst);
794
+ (void) new (s->inst_) int[ninst];
795
+ memmove(s->inst_, inst, instmem);
771
796
  s->ninst_ = ninst;
772
797
  s->flag_ = flag;
773
798
  if (ExtraDebug)
774
- fprintf(stderr, " -> %s\n", DumpState(s).c_str());
799
+ absl::FPrintF(stderr, " -> %s\n", DumpState(s));
775
800
 
776
801
  // Put state in cache and return it.
777
802
  state_cache_.insert(s);
@@ -785,12 +810,12 @@ void DFA::ClearCache() {
785
810
  while (begin != end) {
786
811
  StateSet::iterator tmp = begin;
787
812
  ++begin;
813
+ // Deallocate the instruction array, which is stored separately as above.
814
+ std::allocator<int>().deallocate((*tmp)->inst_, (*tmp)->ninst_);
788
815
  // Deallocate the blob of memory that we allocated in DFA::CachedState().
789
816
  // We recompute mem in order to benefit from sized delete where possible.
790
- int ninst = (*tmp)->ninst_;
791
817
  int nnext = prog_->bytemap_range() + 1; // + 1 for kByteEndText slot
792
- int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>) +
793
- ninst*sizeof(int);
818
+ int mem = sizeof(State) + nnext*sizeof(std::atomic<State*>);
794
819
  std::allocator<char>().deallocate(reinterpret_cast<char*>(*tmp), mem);
795
820
  }
796
821
  state_cache_.clear();
@@ -985,8 +1010,8 @@ void DFA::RunWorkqOnByte(Workq* oldq, Workq* newq,
985
1010
  }
986
1011
 
987
1012
  if (ExtraDebug)
988
- fprintf(stderr, "%s on %d[%#x] -> %s [%d]\n",
989
- DumpWorkq(oldq).c_str(), c, flag, DumpWorkq(newq).c_str(), *ismatch);
1013
+ absl::FPrintF(stderr, "%s on %d[%#x] -> %s [%d]\n",
1014
+ DumpWorkq(oldq), c, flag, DumpWorkq(newq), *ismatch);
990
1015
  }
991
1016
 
992
1017
  // Processes input byte c in state, returning new state.
@@ -994,7 +1019,7 @@ void DFA::RunWorkqOnByte(Workq* oldq, Workq* newq,
994
1019
  DFA::State* DFA::RunStateOnByteUnlocked(State* state, int c) {
995
1020
  // Keep only one RunStateOnByte going
996
1021
  // even if the DFA is being run by multiple threads.
997
- MutexLock l(&mutex_);
1022
+ absl::MutexLock l(&mutex_);
998
1023
  return RunStateOnByte(state, c);
999
1024
  }
1000
1025
 
@@ -1134,9 +1159,9 @@ DFA::RWLocker::RWLocker(CacheMutex* mu) : mu_(mu), writing_(false) {
1134
1159
  mu_->ReaderLock();
1135
1160
  }
1136
1161
 
1137
- // This function is marked as NO_THREAD_SAFETY_ANALYSIS because
1162
+ // This function is marked as ABSL_NO_THREAD_SAFETY_ANALYSIS because
1138
1163
  // the annotations don't support lock upgrade.
1139
- void DFA::RWLocker::LockForWriting() NO_THREAD_SAFETY_ANALYSIS {
1164
+ void DFA::RWLocker::LockForWriting() ABSL_NO_THREAD_SAFETY_ANALYSIS {
1140
1165
  if (!writing_) {
1141
1166
  mu_->ReaderUnlock();
1142
1167
  mu_->WriterLock();
@@ -1246,7 +1271,7 @@ DFA::StateSaver::~StateSaver() {
1246
1271
  DFA::State* DFA::StateSaver::Restore() {
1247
1272
  if (is_special_)
1248
1273
  return special_;
1249
- MutexLock l(&dfa_->mutex_);
1274
+ absl::MutexLock l(&dfa_->mutex_);
1250
1275
  State* s = dfa_->CachedState(inst_, ninst_, flag_);
1251
1276
  if (s == NULL)
1252
1277
  LOG(DFATAL) << "StateSaver failed to restore state.";
@@ -1342,13 +1367,13 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
1342
1367
 
1343
1368
  State* s = start;
1344
1369
  if (ExtraDebug)
1345
- fprintf(stderr, "@stx: %s\n", DumpState(s).c_str());
1370
+ absl::FPrintF(stderr, "@stx: %s\n", DumpState(s));
1346
1371
 
1347
1372
  if (s->IsMatch()) {
1348
1373
  matched = true;
1349
1374
  lastmatch = p;
1350
1375
  if (ExtraDebug)
1351
- fprintf(stderr, "match @stx! [%s]\n", DumpState(s).c_str());
1376
+ absl::FPrintF(stderr, "match @stx! [%s]\n", DumpState(s));
1352
1377
  if (params->matches != NULL && kind_ == Prog::kManyMatch) {
1353
1378
  for (int i = s->ninst_ - 1; i >= 0; i--) {
1354
1379
  int id = s->inst_[i];
@@ -1365,7 +1390,7 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
1365
1390
 
1366
1391
  while (p != ep) {
1367
1392
  if (ExtraDebug)
1368
- fprintf(stderr, "@%td: %s\n", p - bp, DumpState(s).c_str());
1393
+ absl::FPrintF(stderr, "@%d: %s\n", p - bp, DumpState(s));
1369
1394
 
1370
1395
  if (can_prefix_accel && s == start) {
1371
1396
  // In start state, only way out is to find the prefix,
@@ -1465,7 +1490,7 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
1465
1490
  else
1466
1491
  lastmatch = p + 1;
1467
1492
  if (ExtraDebug)
1468
- fprintf(stderr, "match @%td! [%s]\n", lastmatch - bp, DumpState(s).c_str());
1493
+ absl::FPrintF(stderr, "match @%d! [%s]\n", lastmatch - bp, DumpState(s));
1469
1494
  if (params->matches != NULL && kind_ == Prog::kManyMatch) {
1470
1495
  for (int i = s->ninst_ - 1; i >= 0; i--) {
1471
1496
  int id = s->inst_[i];
@@ -1484,7 +1509,7 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
1484
1509
  // Process one more byte to see if it triggers a match.
1485
1510
  // (Remember, matches are delayed one byte.)
1486
1511
  if (ExtraDebug)
1487
- fprintf(stderr, "@etx: %s\n", DumpState(s).c_str());
1512
+ absl::FPrintF(stderr, "@etx: %s\n", DumpState(s));
1488
1513
 
1489
1514
  int lastbyte;
1490
1515
  if (run_forward) {
@@ -1532,7 +1557,7 @@ inline bool DFA::InlinedSearchLoop(SearchParams* params) {
1532
1557
  matched = true;
1533
1558
  lastmatch = p;
1534
1559
  if (ExtraDebug)
1535
- fprintf(stderr, "match @etx! [%s]\n", DumpState(s).c_str());
1560
+ absl::FPrintF(stderr, "match @etx! [%s]\n", DumpState(s));
1536
1561
  if (params->matches != NULL && kind_ == Prog::kManyMatch) {
1537
1562
  for (int i = s->ninst_ - 1; i >= 0; i--) {
1538
1563
  int id = s->inst_[i];
@@ -1623,8 +1648,8 @@ bool DFA::FastSearchLoop(SearchParams* params) {
1623
1648
  // state for the DFA search loop. Fills in params and returns true on success.
1624
1649
  // Returns false on failure.
1625
1650
  bool DFA::AnalyzeSearch(SearchParams* params) {
1626
- const StringPiece& text = params->text;
1627
- const StringPiece& context = params->context;
1651
+ absl::string_view text = params->text;
1652
+ absl::string_view context = params->context;
1628
1653
 
1629
1654
  // Sanity check: make sure that text lies within context.
1630
1655
  if (BeginPtr(text) < BeginPtr(context) || EndPtr(text) > EndPtr(context)) {
@@ -1694,9 +1719,9 @@ bool DFA::AnalyzeSearch(SearchParams* params) {
1694
1719
  params->can_prefix_accel = true;
1695
1720
 
1696
1721
  if (ExtraDebug)
1697
- fprintf(stderr, "anchored=%d fwd=%d flags=%#x state=%s can_prefix_accel=%d\n",
1698
- params->anchored, params->run_forward, flags,
1699
- DumpState(params->start).c_str(), params->can_prefix_accel);
1722
+ absl::FPrintF(stderr, "anchored=%d fwd=%d flags=%#x state=%s can_prefix_accel=%d\n",
1723
+ params->anchored, params->run_forward, flags,
1724
+ DumpState(params->start), params->can_prefix_accel);
1700
1725
 
1701
1726
  return true;
1702
1727
  }
@@ -1709,7 +1734,7 @@ bool DFA::AnalyzeSearchHelper(SearchParams* params, StartInfo* info,
1709
1734
  if (start != NULL)
1710
1735
  return true;
1711
1736
 
1712
- MutexLock l(&mutex_);
1737
+ absl::MutexLock l(&mutex_);
1713
1738
  start = info->start.load(std::memory_order_relaxed);
1714
1739
  if (start != NULL)
1715
1740
  return true;
@@ -1728,14 +1753,9 @@ bool DFA::AnalyzeSearchHelper(SearchParams* params, StartInfo* info,
1728
1753
  }
1729
1754
 
1730
1755
  // The actual DFA search: calls AnalyzeSearch and then FastSearchLoop.
1731
- bool DFA::Search(const StringPiece& text,
1732
- const StringPiece& context,
1733
- bool anchored,
1734
- bool want_earliest_match,
1735
- bool run_forward,
1736
- bool* failed,
1737
- const char** epp,
1738
- SparseSet* matches) {
1756
+ bool DFA::Search(absl::string_view text, absl::string_view context,
1757
+ bool anchored, bool want_earliest_match, bool run_forward,
1758
+ bool* failed, const char** epp, SparseSet* matches) {
1739
1759
  *epp = NULL;
1740
1760
  if (!ok()) {
1741
1761
  *failed = true;
@@ -1744,9 +1764,9 @@ bool DFA::Search(const StringPiece& text,
1744
1764
  *failed = false;
1745
1765
 
1746
1766
  if (ExtraDebug) {
1747
- fprintf(stderr, "\nprogram:\n%s\n", prog_->DumpUnanchored().c_str());
1748
- fprintf(stderr, "text %s anchored=%d earliest=%d fwd=%d kind %d\n",
1749
- std::string(text).c_str(), anchored, want_earliest_match, run_forward, kind_);
1767
+ absl::FPrintF(stderr, "\nprogram:\n%s\n", prog_->DumpUnanchored());
1768
+ absl::FPrintF(stderr, "text %s anchored=%d earliest=%d fwd=%d kind %d\n",
1769
+ text, anchored, want_earliest_match, run_forward, kind_);
1750
1770
  }
1751
1771
 
1752
1772
  RWLocker l(&cache_mutex_);
@@ -1770,7 +1790,7 @@ bool DFA::Search(const StringPiece& text,
1770
1790
  return true;
1771
1791
  }
1772
1792
  if (ExtraDebug)
1773
- fprintf(stderr, "start %s\n", DumpState(params.start).c_str());
1793
+ absl::FPrintF(stderr, "start %s\n", DumpState(params.start));
1774
1794
  bool ret = FastSearchLoop(&params);
1775
1795
  if (params.failed) {
1776
1796
  *failed = true;
@@ -1789,17 +1809,17 @@ DFA* Prog::GetDFA(MatchKind kind) {
1789
1809
  // "longest match" DFA, because RE2 never does reverse
1790
1810
  // "first match" searches.
1791
1811
  if (kind == kFirstMatch) {
1792
- std::call_once(dfa_first_once_, [](Prog* prog) {
1812
+ absl::call_once(dfa_first_once_, [](Prog* prog) {
1793
1813
  prog->dfa_first_ = new DFA(prog, kFirstMatch, prog->dfa_mem_ / 2);
1794
1814
  }, this);
1795
1815
  return dfa_first_;
1796
1816
  } else if (kind == kManyMatch) {
1797
- std::call_once(dfa_first_once_, [](Prog* prog) {
1817
+ absl::call_once(dfa_first_once_, [](Prog* prog) {
1798
1818
  prog->dfa_first_ = new DFA(prog, kManyMatch, prog->dfa_mem_);
1799
1819
  }, this);
1800
1820
  return dfa_first_;
1801
1821
  } else {
1802
- std::call_once(dfa_longest_once_, [](Prog* prog) {
1822
+ absl::call_once(dfa_longest_once_, [](Prog* prog) {
1803
1823
  if (!prog->reversed_)
1804
1824
  prog->dfa_longest_ = new DFA(prog, kLongestMatch, prog->dfa_mem_ / 2);
1805
1825
  else
@@ -1823,12 +1843,11 @@ void Prog::DeleteDFA(DFA* dfa) {
1823
1843
  //
1824
1844
  // This is the only external interface (class DFA only exists in this file).
1825
1845
  //
1826
- bool Prog::SearchDFA(const StringPiece& text, const StringPiece& const_context,
1827
- Anchor anchor, MatchKind kind, StringPiece* match0,
1846
+ bool Prog::SearchDFA(absl::string_view text, absl::string_view context,
1847
+ Anchor anchor, MatchKind kind, absl::string_view* match0,
1828
1848
  bool* failed, SparseSet* matches) {
1829
1849
  *failed = false;
1830
1850
 
1831
- StringPiece context = const_context;
1832
1851
  if (context.data() == NULL)
1833
1852
  context = text;
1834
1853
  bool caret = anchor_start();
@@ -1889,10 +1908,10 @@ bool Prog::SearchDFA(const StringPiece& text, const StringPiece& const_context,
1889
1908
  if (match0) {
1890
1909
  if (reversed_)
1891
1910
  *match0 =
1892
- StringPiece(ep, static_cast<size_t>(text.data() + text.size() - ep));
1911
+ absl::string_view(ep, static_cast<size_t>(text.data() + text.size() - ep));
1893
1912
  else
1894
1913
  *match0 =
1895
- StringPiece(text.data(), static_cast<size_t>(ep - text.data()));
1914
+ absl::string_view(text.data(), static_cast<size_t>(ep - text.data()));
1896
1915
  }
1897
1916
  return true;
1898
1917
  }
@@ -1905,7 +1924,7 @@ int DFA::BuildAllStates(const Prog::DFAStateCallback& cb) {
1905
1924
  // Pick out start state for unanchored search
1906
1925
  // at beginning of text.
1907
1926
  RWLocker l(&cache_mutex_);
1908
- SearchParams params(StringPiece(), StringPiece(), &l);
1927
+ SearchParams params(absl::string_view(), absl::string_view(), &l);
1909
1928
  params.anchored = false;
1910
1929
  if (!AnalyzeSearch(&params) ||
1911
1930
  params.start == NULL ||
@@ -1915,7 +1934,7 @@ int DFA::BuildAllStates(const Prog::DFAStateCallback& cb) {
1915
1934
  // Add start state to work queue.
1916
1935
  // Note that any State* that we handle here must point into the cache,
1917
1936
  // so we can simply depend on pointer-as-a-number hashing and equality.
1918
- std::unordered_map<State*, int> m;
1937
+ absl::flat_hash_map<State*, int> m;
1919
1938
  std::deque<State*> q;
1920
1939
  m.emplace(params.start, static_cast<int>(m.size()));
1921
1940
  q.push_back(params.start);
@@ -1989,11 +2008,11 @@ bool DFA::PossibleMatchRange(std::string* min, std::string* max, int maxlen) {
1989
2008
  // Also note that previously_visited_states[UnseenStatePtr] will, in the STL
1990
2009
  // tradition, implicitly insert a '0' value at first use. We take advantage
1991
2010
  // of that property below.
1992
- std::unordered_map<State*, int> previously_visited_states;
2011
+ absl::flat_hash_map<State*, int> previously_visited_states;
1993
2012
 
1994
2013
  // Pick out start state for anchored search at beginning of text.
1995
2014
  RWLocker l(&cache_mutex_);
1996
- SearchParams params(StringPiece(), StringPiece(), &l);
2015
+ SearchParams params(absl::string_view(), absl::string_view(), &l);
1997
2016
  params.anchored = true;
1998
2017
  if (!AnalyzeSearch(&params))
1999
2018
  return false;
@@ -2033,7 +2052,7 @@ bool DFA::PossibleMatchRange(std::string* min, std::string* max, int maxlen) {
2033
2052
  // Build minimum prefix.
2034
2053
  State* s = params.start;
2035
2054
  min->clear();
2036
- MutexLock lock(&mutex_);
2055
+ absl::MutexLock lock(&mutex_);
2037
2056
  for (int i = 0; i < maxlen; i++) {
2038
2057
  if (previously_visited_states[s] > kMaxEltRepetitions)
2039
2058
  break;
@@ -8,7 +8,6 @@
8
8
  #include <string>
9
9
  #include <utility>
10
10
 
11
- #include "util/util.h"
12
11
  #include "util/logging.h"
13
12
  #include "re2/prefilter.h"
14
13
  #include "re2/prefilter_tree.h"
@@ -46,7 +45,7 @@ FilteredRE2& FilteredRE2::operator=(FilteredRE2&& other) {
46
45
  return *this;
47
46
  }
48
47
 
49
- RE2::ErrorCode FilteredRE2::Add(const StringPiece& pattern,
48
+ RE2::ErrorCode FilteredRE2::Add(absl::string_view pattern,
50
49
  const RE2::Options& options, int* id) {
51
50
  RE2* re = new RE2(pattern, options);
52
51
  RE2::ErrorCode code = re->error_code();
@@ -85,14 +84,14 @@ void FilteredRE2::Compile(std::vector<std::string>* atoms) {
85
84
  compiled_ = true;
86
85
  }
87
86
 
88
- int FilteredRE2::SlowFirstMatch(const StringPiece& text) const {
87
+ int FilteredRE2::SlowFirstMatch(absl::string_view text) const {
89
88
  for (size_t i = 0; i < re2_vec_.size(); i++)
90
89
  if (RE2::PartialMatch(text, *re2_vec_[i]))
91
90
  return static_cast<int>(i);
92
91
  return -1;
93
92
  }
94
93
 
95
- int FilteredRE2::FirstMatch(const StringPiece& text,
94
+ int FilteredRE2::FirstMatch(absl::string_view text,
96
95
  const std::vector<int>& atoms) const {
97
96
  if (!compiled_) {
98
97
  LOG(DFATAL) << "FirstMatch called before Compile.";
@@ -106,10 +105,9 @@ int FilteredRE2::FirstMatch(const StringPiece& text,
106
105
  return -1;
107
106
  }
108
107
 
109
- bool FilteredRE2::AllMatches(
110
- const StringPiece& text,
111
- const std::vector<int>& atoms,
112
- std::vector<int>* matching_regexps) const {
108
+ bool FilteredRE2::AllMatches(absl::string_view text,
109
+ const std::vector<int>& atoms,
110
+ std::vector<int>* matching_regexps) const {
113
111
  matching_regexps->clear();
114
112
  std::vector<int> regexps;
115
113
  prefilter_tree_->RegexpsGivenStrings(atoms, &regexps);
@@ -119,9 +117,8 @@ bool FilteredRE2::AllMatches(
119
117
  return !matching_regexps->empty();
120
118
  }
121
119
 
122
- void FilteredRE2::AllPotentials(
123
- const std::vector<int>& atoms,
124
- std::vector<int>* potential_regexps) const {
120
+ void FilteredRE2::AllPotentials(const std::vector<int>& atoms,
121
+ std::vector<int>* potential_regexps) const {
125
122
  prefilter_tree_->RegexpsGivenStrings(atoms, potential_regexps);
126
123
  }
127
124
 
@@ -25,6 +25,7 @@
25
25
  #include <string>
26
26
  #include <vector>
27
27
 
28
+ #include "absl/strings/string_view.h"
28
29
  #include "re2/re2.h"
29
30
 
30
31
  namespace re2 {
@@ -47,7 +48,7 @@ class FilteredRE2 {
47
48
  // Uses RE2 constructor to create a RE2 object (re). Returns
48
49
  // re->error_code(). If error_code is other than NoError, then re is
49
50
  // deleted and not added to re2_vec_.
50
- RE2::ErrorCode Add(const StringPiece& pattern,
51
+ RE2::ErrorCode Add(absl::string_view pattern,
51
52
  const RE2::Options& options,
52
53
  int* id);
53
54
 
@@ -63,17 +64,17 @@ class FilteredRE2 {
63
64
  // Returns -1 on no match. Can be called prior to Compile.
64
65
  // Does not do any filtering: simply tries to Match the
65
66
  // regexps in a loop.
66
- int SlowFirstMatch(const StringPiece& text) const;
67
+ int SlowFirstMatch(absl::string_view text) const;
67
68
 
68
69
  // Returns the index of the first matching regexp.
69
70
  // Returns -1 on no match. Compile has to be called before
70
71
  // calling this.
71
- int FirstMatch(const StringPiece& text,
72
+ int FirstMatch(absl::string_view text,
72
73
  const std::vector<int>& atoms) const;
73
74
 
74
75
  // Returns the indices of all matching regexps, after first clearing
75
76
  // matched_regexps.
76
- bool AllMatches(const StringPiece& text,
77
+ bool AllMatches(absl::string_view text,
77
78
  const std::vector<int>& atoms,
78
79
  std::vector<int>* matching_regexps) const;
79
80