summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Hiesel <hiesel@google.com>2022-01-28 10:40:52 +0100
committerLuca Milanesio <luca.milanesio@gmail.com>2022-03-02 16:51:20 +0000
commit80d90858ad98c4e274439a6fe628a4260a28cfdf (patch)
tree94022f0446d5051d0c9d39f563047e08e5fd7139
parent81254a8e27dcd9c303a0300ca57ddee37534cb54 (diff)
Memoize compiled RefPattern in ProjectCache
Compiling regular expressions is known to be expensive. If the access section contains a regular expression, we pre compile and memoize it. Release-Notes: Memoize reg-ex compilation in projects cache Change-Id: I84f50323e9f08e69ab6414203927c7d2eacb23e4 (cherry picked from commit e235c42b099138f713ceef034923bfd7731f75ad)
-rw-r--r--java/com/google/gerrit/entities/AccessSection.java16
-rw-r--r--java/com/google/gerrit/server/project/RefPatternMatcher.java12
-rw-r--r--java/com/google/gerrit/server/project/SectionMatcher.java2
3 files changed, 29 insertions, 1 deletions
diff --git a/java/com/google/gerrit/entities/AccessSection.java b/java/com/google/gerrit/entities/AccessSection.java
index 69a234a5c4..8ae0a5dbed 100644
--- a/java/com/google/gerrit/entities/AccessSection.java
+++ b/java/com/google/gerrit/entities/AccessSection.java
@@ -18,12 +18,14 @@ import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.util.Objects.requireNonNull;
import com.google.auto.value.AutoValue;
+import com.google.auto.value.extension.memoized.Memoized;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.common.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
+import java.util.regex.Pattern;
/** Portion of a {@link Project} describing access rules. */
@AutoValue
@@ -42,6 +44,20 @@ public abstract class AccessSection implements Comparable<AccessSection> {
/** Name of the access section. It could be a ref pattern or something else. */
public abstract String getName();
+ /**
+ * A compiled regular expression in case {@link #getName()} is a regular expression. This is
+ * memoized to save callers from compiling patterns for every use.
+ */
+ @Memoized
+ public Optional<Pattern> getNamePattern() {
+ if (isValidRefSectionName(getName())
+ && getName().startsWith(REGEX_PREFIX)
+ && !getName().contains("${")) {
+ return Optional.of(Pattern.compile(getName()));
+ }
+ return Optional.empty();
+ }
+
public abstract ImmutableList<Permission> getPermissions();
public static AccessSection create(String name) {
diff --git a/java/com/google/gerrit/server/project/RefPatternMatcher.java b/java/com/google/gerrit/server/project/RefPatternMatcher.java
index b9076b3db6..be840b5b23 100644
--- a/java/com/google/gerrit/server/project/RefPatternMatcher.java
+++ b/java/com/google/gerrit/server/project/RefPatternMatcher.java
@@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import com.google.gerrit.common.data.ParameterizedString;
+import com.google.gerrit.entities.AccessSection;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.server.CurrentUser;
@@ -32,6 +33,13 @@ import java.util.regex.Pattern;
import java.util.stream.Stream;
public abstract class RefPatternMatcher {
+ public static RefPatternMatcher getMatcher(AccessSection section) {
+ if (section.getNamePattern().isPresent()) {
+ return new Regexp(section.getNamePattern().get());
+ }
+ return getMatcher(section.getName());
+ }
+
public static RefPatternMatcher getMatcher(String pattern) {
if (containsParameters(pattern)) {
return new ExpandParameters(pattern);
@@ -79,6 +87,10 @@ public abstract class RefPatternMatcher {
pattern = Pattern.compile(re);
}
+ Regexp(Pattern re) {
+ pattern = re;
+ }
+
@Override
public boolean match(String ref, CurrentUser user) {
return pattern.matcher(ref).matches() || (isRE(ref) && pattern.pattern().equals(ref));
diff --git a/java/com/google/gerrit/server/project/SectionMatcher.java b/java/com/google/gerrit/server/project/SectionMatcher.java
index 763957e03e..3d7175fa61 100644
--- a/java/com/google/gerrit/server/project/SectionMatcher.java
+++ b/java/com/google/gerrit/server/project/SectionMatcher.java
@@ -28,7 +28,7 @@ public class SectionMatcher extends RefPatternMatcher {
static SectionMatcher wrap(Project.NameKey project, AccessSection section) {
String ref = section.getName();
if (AccessSection.isValidRefSectionName(ref)) {
- return new SectionMatcher(project, section, getMatcher(ref));
+ return new SectionMatcher(project, section, getMatcher(section));
}
return null;
}