Compute num_captures_ eagerly.
Change-Id: I7f77eece4c553956e61c746a77c72e095fb1d0e5
Reviewed-on: https://code-review.googlesource.com/c/36874
Reviewed-by: Paul Wankadia <[email protected]>
diff --git a/re2/re2.cc b/re2/re2.cc
index f3f96ae..4e42f8b 100644
--- a/re2/re2.cc
+++ b/re2/re2.cc
@@ -177,10 +177,10 @@
entire_regexp_ = NULL;
suffix_regexp_ = NULL;
prog_ = NULL;
+ num_captures_ = -1;
rprog_ = NULL;
error_ = empty_string;
error_code_ = NoError;
- num_captures_ = -1;
named_groups_ = NULL;
group_names_ = NULL;
@@ -218,6 +218,11 @@
return;
}
+ // We used to compute this lazily, but it's used during the
+ // typical control flow for a match call, so we now compute
+ // it eagerly, which avoids the overhead of std::once_flag.
+ num_captures_ = suffix_regexp_->NumCaptures();
+
// Could delay this until the first match call that
// cares about submatch information, but the one-pass
// machine's memory gets cut from the DFA memory budget,
@@ -301,16 +306,6 @@
return Fanout(prog, histogram);
}
-// Returns num_captures_, computing it if needed, or -1 if the
-// regexp wasn't valid on construction.
-int RE2::NumberOfCapturingGroups() const {
- std::call_once(num_captures_once_, [](const RE2* re) {
- if (re->suffix_regexp_ != NULL)
- re->num_captures_ = re->suffix_regexp_->NumCaptures();
- }, this);
- return num_captures_;
-}
-
// Returns named_groups_, computing it if needed.
const std::map<string, int>& RE2::NamedCapturingGroups() const {
std::call_once(named_groups_once_, [](const RE2* re) {
diff --git a/re2/re2.h b/re2/re2.h
index c93de56..f846029 100644
--- a/re2/re2.h
+++ b/re2/re2.h
@@ -479,7 +479,7 @@
// Return the number of capturing subpatterns, or -1 if the
// regexp wasn't valid on construction. The overall match ($0)
// does not count: if the regexp is "(a)(b)", returns 2.
- int NumberOfCapturingGroups() const;
+ int NumberOfCapturingGroups() const { return num_captures_; }
// Return a map from names to capturing indices.
// The map records the index of the leftmost group
@@ -744,6 +744,7 @@
re2::Regexp* entire_regexp_; // parsed regular expression
re2::Regexp* suffix_regexp_; // parsed regular expression, prefix removed
re2::Prog* prog_; // compiled program for regexp
+ int num_captures_; // Number of capturing groups
bool is_one_pass_; // can use prog_->SearchOnePass?
mutable re2::Prog* rprog_; // reverse program for regexp
@@ -751,7 +752,6 @@
// (or points to empty string)
mutable ErrorCode error_code_; // Error code
mutable string error_arg_; // Fragment of regexp showing error
- mutable int num_captures_; // Number of capturing groups
// Map from capture names to indices
mutable const std::map<string, int>* named_groups_;
@@ -761,7 +761,6 @@
// Onces for lazy computations.
mutable std::once_flag rprog_once_;
- mutable std::once_flag num_captures_once_;
mutable std::once_flag named_groups_once_;
mutable std::once_flag group_names_once_;