Cache depends on by change per thread
Caching depends on by change per thread improves the performance
of queries such as "change:<> has:a_depends-on --depends-on--all" by
3ms against ES index backend (i.e. on avg took 20ms before and 17ms
after this change over 50 samples). This improvement is due to the fact
that has:a_depends-on and --depends-on--all computes the same
depends-on information.
One can also benefit from this performance improvement when using
has:a_depends-on and in_depends-on:<> operators in Task plugin config.
Change-Id: Ia97f08bf8c0e607a4044db281f191bdd7ebe3f03
diff --git a/src/main/java/com/googlesource/gerrit/plugins/depends/on/ChangeMessageStore.java b/src/main/java/com/googlesource/gerrit/plugins/depends/on/ChangeMessageStore.java
index 0bc8122..67f5040 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/depends/on/ChangeMessageStore.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/depends/on/ChangeMessageStore.java
@@ -25,6 +25,7 @@
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.cache.PerThreadCache;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.notedb.ChangeNotes;
@@ -38,7 +39,9 @@
import com.googlesource.gerrit.plugins.depends.on.extensions.DependencyResolver;
import com.googlesource.gerrit.plugins.depends.on.formats.Comment;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -48,6 +51,11 @@
public class ChangeMessageStore implements DependencyResolver {
private static final Logger log = LoggerFactory.getLogger(ChangeMessageStore.class);
+ public static class DependsOnByChangeCache extends HashMap {}
+
+ protected static final PerThreadCache.Key<DependsOnByChangeCache> DEPENDS_ON_BY_CHANGE_CACHE_KEY =
+ PerThreadCache.Key.create(DependsOnByChangeCache.class);
+
public interface Factory {
ChangeMessageStore create();
}
@@ -104,6 +112,17 @@
}
public List<DependsOn> loadWithOrder(ChangeNotes changeNotes) throws StorageException {
+ PerThreadCache perThreadCache = PerThreadCache.get();
+ if (perThreadCache != null) {
+ Map<Change.Id, List<DependsOn>> dependsOnByChangeCache =
+ perThreadCache.get(DEPENDS_ON_BY_CHANGE_CACHE_KEY, DependsOnByChangeCache::new);
+ return dependsOnByChangeCache.computeIfAbsent(
+ changeNotes.getChangeId(), (id) -> loadWithOrderFromNoteDb(changeNotes));
+ }
+ return loadWithOrderFromNoteDb(changeNotes);
+ }
+
+ private List<DependsOn> loadWithOrderFromNoteDb(ChangeNotes changeNotes) throws StorageException {
for (ChangeMessage message : Lists.reverse(cmUtil.byChange(changeNotes))) {
Optional<List<DependsOn>> deps = Comment.from(message.getMessage());
if (deps.isPresent()) {