test_class.file: extra/src/test/java/org/wikimedia/search/extra/latency/SearchLatencyListenerTest.java
test_class.identifier: SearchLatencyListenerTest
test_class.superclass: extends RandomizedTest
test_case.body: @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));
          // Without rotation this must still be 0
          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));
          // rotating without any data should not change the latency
          assertEquals(tookInNanos, stat.getLatency().nanos(), delta(tookInNanos));
      }
test_case.class_method_signature: SearchLatencyListenerTest.rotate()
test_case.full_signature: @Test public void rotate()
test_case.identifier: rotate
test_case.invocations: singleton newListener onQueryPhase mockSearchContext singletonList assertEquals size getLatencyStats get getLatencyStats assertNotNull assertEquals getBucket assertEquals getPercentile ulp assertEquals nanos getLatency ulp rotate assertEquals size getLatencyStats get getLatencyStats assertNotNull assertEquals getBucket assertEquals getPercentile ulp assertEquals nanos getLatency delta rotate assertEquals size getLatencyStats get getLatencyStats assertNotNull assertEquals getBucket assertEquals getPercentile ulp assertEquals nanos getLatency delta
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void rotate()
focal_class.declarator: ROTATION_DELAY = TimeValue.timeValueSeconds(5)
focal_class.modifier: private static final
focal_class.original_string: private static final TimeValue ROTATION_DELAY = TimeValue.timeValueSeconds(5);
focal_class.type: TimeValue
focal_class.var_name: ROTATION_DELAY
focal_class.declarator: NUM_ROLLING_HISTOGRAMS = (int) (TimeValue.timeValueMinutes(1).millis() / ROTATION_DELAY.millis())
focal_class.modifier: @VisibleForTesting
      static final
focal_class.original_string: @VisibleForTesting
      static final int NUM_ROLLING_HISTOGRAMS = (int) (TimeValue.timeValueMinutes(1).millis() / ROTATION_DELAY.millis());
focal_class.type: int
focal_class.var_name: NUM_ROLLING_HISTOGRAMS
focal_class.declarator: HIGHEST_TRACKABLE_VALUE = TimeValue.timeValueMinutes(5)
focal_class.modifier: private static final
focal_class.original_string: private static final TimeValue HIGHEST_TRACKABLE_VALUE = TimeValue.timeValueMinutes(5);
focal_class.type: TimeValue
focal_class.var_name: HIGHEST_TRACKABLE_VALUE
focal_class.declarator: LOWEST_DISCERNABLE_VALUE = TimeValue.timeValueMillis(1)
focal_class.modifier: private static final
focal_class.original_string: private static final TimeValue LOWEST_DISCERNABLE_VALUE = TimeValue.timeValueMillis(1);
focal_class.type: TimeValue
focal_class.var_name: LOWEST_DISCERNABLE_VALUE
focal_class.declarator: SIGNIFICANT_DIGITS = 2
focal_class.modifier: static final
focal_class.original_string: static final int SIGNIFICANT_DIGITS = 2;
focal_class.type: int
focal_class.var_name: SIGNIFICANT_DIGITS
focal_class.declarator: statBuckets
focal_class.modifier: private final
focal_class.original_string: private final ConcurrentMap<String, RollingHistogram> statBuckets;
focal_class.type: ConcurrentMap<String, RollingHistogram>
focal_class.var_name: statBuckets
focal_class.declarator: threadPoolSupplier
focal_class.modifier: private final
focal_class.original_string: private final Supplier<ThreadPool> threadPoolSupplier;
focal_class.type: Supplier<ThreadPool>
focal_class.var_name: threadPoolSupplier
focal_class.declarator: cancelRotation
focal_class.modifier: @Nullable private
focal_class.original_string: @Nullable private ThreadPool.Cancellable cancelRotation;
focal_class.type: ThreadPool.Cancellable
focal_class.var_name: cancelRotation
focal_class.file: extra/src/main/java/org/wikimedia/search/extra/latency/SearchLatencyListener.java
focal_class.identifier: SearchLatencyListener
focal_class.interfaces: implements SearchOperationListener, SearchLatencyProbe
focal_class.class_method_signature: SearchLatencyListener.SearchLatencyListener(Settings settings, Supplier<ThreadPool> threadPoolSupplier)
focal_class.full_signature: public  SearchLatencyListener(Settings settings, Supplier<ThreadPool> threadPoolSupplier)
focal_class.identifier: SearchLatencyListener
focal_class.modifiers: public
focal_class.parameters: (Settings settings, Supplier<ThreadPool> threadPoolSupplier)
focal_class.signature:  SearchLatencyListener(Settings settings, Supplier<ThreadPool> threadPoolSupplier)
focal_class.class_method_signature: SearchLatencyListener.doStart()
focal_class.full_signature: @Override protected void doStart()
focal_class.identifier: doStart
focal_class.modifiers: @Override protected
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void doStart()
focal_class.class_method_signature: SearchLatencyListener.doStop()
focal_class.full_signature: @Override protected void doStop()
focal_class.identifier: doStop
focal_class.modifiers: @Override protected
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void doStop()
focal_class.class_method_signature: SearchLatencyListener.doClose()
focal_class.full_signature: @Override protected void doClose()
focal_class.identifier: doClose
focal_class.modifiers: @Override protected
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void doClose()
focal_class.class_method_signature: SearchLatencyListener.getBucket(String name)
focal_class.full_signature: private Optional<RollingHistogram> getBucket(String name)
focal_class.identifier: getBucket
focal_class.modifiers: private
focal_class.parameters: (String name)
focal_class.return: Optional<RollingHistogram>
focal_class.signature: Optional<RollingHistogram> getBucket(String name)
focal_class.class_method_signature: SearchLatencyListener.getOrAddBucket(String name)
focal_class.full_signature: private RollingHistogram getOrAddBucket(String name)
focal_class.identifier: getOrAddBucket
focal_class.modifiers: private
focal_class.parameters: (String name)
focal_class.return: RollingHistogram
focal_class.signature: RollingHistogram getOrAddBucket(String name)
focal_class.class_method_signature: SearchLatencyListener.getMillisAtPercentile(String bucket, double percentile)
focal_class.full_signature: public long getMillisAtPercentile(String bucket, double percentile)
focal_class.identifier: getMillisAtPercentile
focal_class.modifiers: public
focal_class.parameters: (String bucket, double percentile)
focal_class.return: long
focal_class.signature: long getMillisAtPercentile(String bucket, double percentile)
focal_class.class_method_signature: SearchLatencyListener.getLatencyStats(Set<Double> percentiles)
focal_class.full_signature: public List<LatencyStat> getLatencyStats(Set<Double> percentiles)
focal_class.identifier: getLatencyStats
focal_class.modifiers: public
focal_class.parameters: (Set<Double> percentiles)
focal_class.return: List<LatencyStat>
focal_class.signature: List<LatencyStat> getLatencyStats(Set<Double> percentiles)
focal_class.class_method_signature: SearchLatencyListener.onQueryPhase(SearchContext searchContext, long tookInNanos)
focal_class.full_signature: @SuppressFBWarnings("PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS") @Override public void onQueryPhase(SearchContext searchContext, long tookInNanos)
focal_class.identifier: onQueryPhase
focal_class.modifiers: @SuppressFBWarnings("PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS") @Override public
focal_class.parameters: (SearchContext searchContext, long tookInNanos)
focal_class.return: void
focal_class.signature: void onQueryPhase(SearchContext searchContext, long tookInNanos)
focal_class.class_method_signature: SearchLatencyListener.rotate()
focal_class.full_signature: @VisibleForTesting void rotate()
focal_class.identifier: rotate
focal_class.modifiers: @VisibleForTesting
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void rotate()
focal_class.superclass: extends AbstractLifecycleComponent
focal_method.body: @VisibleForTesting
      void rotate() {
          Iterator<RollingHistogram> iter = statBuckets.values().iterator();
          while (iter.hasNext()) {
              RollingHistogram hist = iter.next();
              hist.rotate();
              if (hist.isEmpty()) {
                  iter.remove();
              }
          }
      }
focal_method.class_method_signature: SearchLatencyListener.rotate()
focal_method.full_signature: @VisibleForTesting void rotate()
focal_method.identifier: rotate
focal_method.invocations: iterator values hasNext next rotate isEmpty remove
focal_method.modifiers: @VisibleForTesting
focal_method.parameters: ()
focal_method.return: void
focal_method.signature: void rotate()