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;