Compute num_captures_ eagerly. Change-Id: I7f77eece4c553956e61c746a77c72e095fb1d0e5 Reviewed-on: https://code-review.googlesource.com/c/36874 Reviewed-by: Paul Wankadia <junyer@google.com>
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_;