diff options
author | Patrick Hiesel <hiesel@google.com> | 2022-01-28 10:40:52 +0100 |
---|---|---|
committer | Luca Milanesio <luca.milanesio@gmail.com> | 2022-03-02 16:51:20 +0000 |
commit | 80d90858ad98c4e274439a6fe628a4260a28cfdf (patch) | |
tree | 94022f0446d5051d0c9d39f563047e08e5fd7139 | |
parent | 81254a8e27dcd9c303a0300ca57ddee37534cb54 (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)
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; } |