Add metrics for git/upload-pack/*bitmap* misses

JGit packer tracks the number of times that an object was not
found in the bitmap index or if the bitmap index was completely
missing. The Gerrit admin may be interested in knowing that
the incoming traffic is slowed down by excessive bitmap
index misses because of the increase of the overall git-upload-pack
latencies and the impact on the server's throughput.

Also add a specific counter for when the bitmap index is totally
missing, which the Gerrit admin should use for setting alerts
of possible GC cycles being ineffective.

Add the git/upload-pack/bitmap_index_misses_count for beging used
in performance graphs, while the git/upload-pack/no_bitmap_index
should be more suitable for alerts.

Release-Notes: Add metrics for git/upload-pack/bitmap_index_misses_count and a separate one for missing bitmap indexs
Change-Id: Ie76bdcc39073748a5a0c59618cba58d286e08ba9
diff --git a/Documentation/metrics.txt b/Documentation/metrics.txt
index 396715f..5470709 100644
--- a/Documentation/metrics.txt
+++ b/Documentation/metrics.txt
@@ -368,6 +368,12 @@
 * `git/upload-pack/request_count`: Total number of git-upload-pack requests.
 ** `operation`:
    The name of the operation (CLONE, FETCH).
+* `git/upload-pack/bitmap_index_misses_count`: Number of bitmap index misses per request.
+** `operation`:
+   The name of the operation (CLONE, FETCH).
+* `git/upload-pack/no_bitmap_index`: Total number of requests executed without a bitmap index.
+** `operation`:
+   The name of the operation (CLONE, FETCH).
 * `git/upload-pack/phase_counting`: Time spent in the 'Counting...' phase.
 ** `operation`:
    The name of the operation (CLONE, FETCH).
diff --git a/java/com/google/gerrit/server/git/UploadPackMetricsHook.java b/java/com/google/gerrit/server/git/UploadPackMetricsHook.java
index 9164dd3..0e981f2 100644
--- a/java/com/google/gerrit/server/git/UploadPackMetricsHook.java
+++ b/java/com/google/gerrit/server/git/UploadPackMetricsHook.java
@@ -38,6 +38,8 @@
 
   private final Counter1<Operation> requestCount;
   private final Timer1<Operation> counting;
+  private final Histogram1<Operation> bitmapIndexMissesCount;
+  private final Counter1<Operation> noBitmapIndex;
   private final Timer1<Operation> compressing;
   private final Timer1<Operation> negotiating;
   private final Timer1<Operation> searchingForReuse;
@@ -67,6 +69,22 @@
                 .setUnit(Units.MILLISECONDS),
             operationField);
 
+    bitmapIndexMissesCount =
+        metricMaker.newHistogram(
+            "git/upload-pack/bitmap_index_misses_count",
+            new Description("Number of bitmap index misses per request")
+                .setCumulative()
+                .setUnit("misses"),
+            operationField);
+
+    noBitmapIndex =
+        metricMaker.newCounter(
+            "git/upload-pack/no_bitmap_index",
+            new Description("Total number of requests executed without a bitmap index")
+                .setRate()
+                .setUnit("requests"),
+            operationField);
+
     compressing =
         metricMaker.newTimer(
             "git/upload-pack/phase_compressing",
@@ -127,6 +145,12 @@
 
     requestCount.increment(op);
     counting.record(op, stats.getTimeCounting(), MILLISECONDS);
+    long bitmapIndexMisses = stats.getBitmapIndexMisses();
+    if (bitmapIndexMisses < 0) {
+      noBitmapIndex.increment(op);
+    } else {
+      bitmapIndexMissesCount.record(op, bitmapIndexMisses);
+    }
     compressing.record(op, stats.getTimeCompressing(), MILLISECONDS);
     negotiating.record(op, stats.getTimeNegotiating(), MILLISECONDS);
     searchingForReuse.record(op, stats.getTimeSearchingForReuse(), MILLISECONDS);