SearchLatencyListener extends AbstractLifecycleComponent implements SearchOperationListener, SearchLatencyProbe { @VisibleForTesting void rotate() { Iterator<RollingHistogram> iter = statBuckets.values().iterator(); while (iter.hasNext()) { RollingHistogram hist = iter.next(); hist.rotate(); if (hist.isEmpty()) { iter.remove(); } } } SearchLatencyListener(Settings settings, Supplier<ThreadPool> threadPoolSupplier); long getMillisAtPercentile(String bucket, double percentile); List<LatencyStat> getLatencyStats(Set<Double> percentiles); @SuppressFBWarnings("PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS") @Override void onQueryPhase(SearchContext searchContext, long tookInNanos);  }
@Test public void rotate() { final Set<Double> latencies = Collections.singleton(95D); SearchLatencyListener listener = newListener(); long tookInNanos = 12345678; listener.onQueryPhase(mockSearchContext(Collections.singletonList("foo")), tookInNanos); assertEquals(1, listener.getLatencyStats(latencies).size()); SearchLatencyProbe.LatencyStat stat = listener.getLatencyStats(latencies).get(0); assertNotNull(stat); assertEquals("foo", stat.getBucket()); assertEquals(95D, stat.getPercentile(), Math.ulp(95D)); assertEquals(0D, stat.getLatency().nanos(), Math.ulp(0D)); listener.rotate(); assertEquals(1, listener.getLatencyStats(latencies).size()); stat = listener.getLatencyStats(latencies).get(0); assertNotNull(stat); assertEquals("foo", stat.getBucket()); assertEquals(95D, stat.getPercentile(), Math.ulp(95D)); assertEquals(tookInNanos, stat.getLatency().nanos(), delta(tookInNanos)); listener.rotate(); assertEquals(1, listener.getLatencyStats(latencies).size()); stat = listener.getLatencyStats(latencies).get(0); assertNotNull(stat); assertEquals("foo", stat.getBucket()); assertEquals(95D, stat.getPercentile(), Math.ulp(95D)); assertEquals(tookInNanos, stat.getLatency().nanos(), delta(tookInNanos)); }