@Test(dataProvider = "simulatedCounterIterations")
  public void testCounterWithSimulatedRuns(
      int windowLengthInSlots, int[] incrementsPerIteration, long[] expCountsPerIteration) {
    // given
    SlidingWindowCounter<Object> counter = new SlidingWindowCounter<Object>(windowLengthInSlots);
    int numIterations = incrementsPerIteration.length;

    for (int i = 0; i < numIterations; i++) {
      int numIncrements = incrementsPerIteration[i];
      long expCounts = expCountsPerIteration[i];
      // Objects are absent if they were zero both this iteration
      // and the last -- if only this one, we need to report zero.
      boolean expAbsent = ((expCounts == 0) && ((i == 0) || (expCountsPerIteration[i - 1] == 0)));

      // given (for this iteration)
      for (int j = 0; j < numIncrements; j++) {
        counter.incrementCount(ANY_OBJECT);
      }

      // when (for this iteration)
      Map<Object, Long> counts = counter.getCountsThenAdvanceWindow();

      // then (for this iteration)
      if (expAbsent) {
        assertThat(counts).doesNotContainKey(ANY_OBJECT);
      } else {
        assertThat(counts.get(ANY_OBJECT)).isEqualTo(expCounts);
      }
    }
  }
  @Test
  public void newInstanceShouldHaveEmptyCounts() {
    // given
    SlidingWindowCounter<Object> counter =
        new SlidingWindowCounter<Object>(ANY_WINDOW_LENGTH_IN_SLOTS);

    // when
    Map<Object, Long> counts = counter.getCountsThenAdvanceWindow();

    // then
    assertThat(counts).isEmpty();
  }
 private void emitCurrentWindowCounts() {
   Map<Object, Long> counts = counter.getCountsThenAdvanceWindow();
   int actualWindowLengthInSeconds = lastModifiedTracker.secondsSinceOldestModification();
   lastModifiedTracker.markAsModified();
   if (actualWindowLengthInSeconds != windowLengthInSeconds) {
     LOG.warn(
         String.format(
             WINDOW_LENGTH_WARNING_TEMPLATE, actualWindowLengthInSeconds, windowLengthInSeconds));
   }
   emit(counts, actualWindowLengthInSeconds);
 }
 private void countObjAndAck(Tuple tuple) {
   Object obj = tuple.getValue(0);
   counter.incrementCount(obj);
   collector.ack(tuple);
 }