Use a TopKeyMap in HitBooleanMap also Modify the MatchCache to use the new API. This keeps track of the row/columns of the elements with the top 5 loading times. Change-Id: Ic488db4012fdca9700d2c0c9c9348cf7fa0e7927
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/HitBooleanTable.java b/src/main/java/com/googlesource/gerrit/plugins/task/HitBooleanTable.java index adce341..91d7ad4 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/task/HitBooleanTable.java +++ b/src/main/java/com/googlesource/gerrit/plugins/task/HitBooleanTable.java
@@ -21,16 +21,17 @@ * stored in it are all Booleans and uses BitSets to make this very space efficient. */ public class HitBooleanTable<R, C> extends BooleanTable<R, C> implements TracksStatistics { - public static class Statistics { + public static class Statistics<V> { public long hits; public long misses; public long size; public int numberOfRows; public int numberOfColumns; public Long sumNanosecondsLoading; + public TopKeyMap<V> topNanosecondsLoadingKeys = new TopKeyMap<>(); } - protected Statistics statistics; + protected Statistics<TopKeyMap.TableKeyValue<R, C>> statistics; @Override public Boolean get(R r, C c) { @@ -45,19 +46,29 @@ return value; } - public StopWatch createLoadingStopWatch() { + public StopWatch createLoadingStopWatch(R row, C column, boolean isVisible) { if (statistics == null) { return StopWatch.DISABLED; } if (statistics.sumNanosecondsLoading == null) { statistics.sumNanosecondsLoading = 0L; } - return new StopWatch.Enabled().setNanosConsumer(ns -> statistics.sumNanosecondsLoading += ns); + return new StopWatch.Enabled() + .setNanosConsumer( + ns -> + statistics.sumNanosecondsLoading += + updateTopLoadingTimes(ns, row, column, isVisible)); + } + + public long updateTopLoadingTimes(long nanos, R row, C column, boolean isVisible) { + statistics.topNanosecondsLoadingKeys.addIfTop( + nanos, isVisible ? new TopKeyMap.TableKeyValue<R, C>(row, column) : null); + return nanos; } @Override public void initStatistics() { - statistics = new Statistics(); + statistics = new Statistics<>(); } @Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/MatchCache.java b/src/main/java/com/googlesource/gerrit/plugins/task/MatchCache.java index c7f7e41..df0b921 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/task/MatchCache.java +++ b/src/main/java/com/googlesource/gerrit/plugins/task/MatchCache.java
@@ -46,7 +46,8 @@ Boolean isMatched = resultByChangeByQuery.get(query, changeData.getId()); if (isMatched == null) { Matchable<ChangeData> matchable = predicateCache.getPredicate(query, isVisible).asMatchable(); - try (StopWatch stopWatch = resultByChangeByQuery.createLoadingStopWatch()) { + try (StopWatch stopWatch = + resultByChangeByQuery.createLoadingStopWatch(query, changeData.getId(), isVisible)) { isMatched = matchable.match(changeData); resultByChangeByQuery.put(query, changeData.getId(), isMatched); }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TopKeyMap.java b/src/main/java/com/googlesource/gerrit/plugins/task/TopKeyMap.java index a23d59f..5753b52 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/task/TopKeyMap.java +++ b/src/main/java/com/googlesource/gerrit/plugins/task/TopKeyMap.java
@@ -31,6 +31,20 @@ * insertion approach, it is easy to make a TopKeyMap efficiently thread safe. */ public class TopKeyMap<V> { + /** + * A TableKeyValue is a helper class for TopKeyMap use cases, such as a table with with row and + * column keys, which involve two values. + */ + public static class TableKeyValue<R, C> { + public final R row; + public final C column; + + public TableKeyValue(R row, C column) { + this.row = row; + this.column = column; + } + } + protected class Entry { public long key; public V value;