Cache RefControl.isVisible()
In VisibleRefFilter, when VisibleChanges() is evaluated,
the RefControl.isVisible() is calculated for each change
even though they share destination ref.
For a git with many changes, storing the RefControl.isVisible()
can save valuable CPU-cycles. Especially in complex setups with
many rules.
When testing on a (real) project with many Changes and
PermissionRules a noticeable different could be seen:
ls-remote before fix:
real 0m3.024s
real 0m2.304s
real 0m2.654s
real 0m2.754s
real 0m3.474s
real 0m3.494s
ls-remote after fix:
real 0m2.004s
real 0m2.164s
real 0m1.934s
real 0m1.704s
real 0m1.674s
real 0m1.754s
Time for calculating visible refs could be cut down 30-50%.
Change-Id: I1a9f63f1c64cdeaa692429a1534e92b6f10eb62b
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
index 4e6f626..229b062 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java
@@ -58,6 +58,7 @@
private Boolean owner;
private Boolean canForgeAuthor;
private Boolean canForgeCommitter;
+ private Boolean isVisible;
RefControl(ProjectControl projectControl, String ref,
PermissionCollection relevant) {
@@ -103,8 +104,12 @@
/** Can this user see this reference exists? */
public boolean isVisible() {
- return (getCurrentUser() instanceof InternalUser || canPerform(Permission.READ))
- && canRead();
+ if (isVisible == null) {
+ isVisible =
+ (getCurrentUser() instanceof InternalUser || canPerform(Permission.READ))
+ && canRead();
+ }
+ return isVisible;
}
/**