Ensure SlidingWindowCounter is advanced in correct order prior to building the complete window
Change-Id: Ie58cb48cf4af5e29fdc48e02ec53e37b326b0340
(cherry picked from commit 322a624e60cc4367f0a041129d6721aee007a127)
diff --git a/utils/misc/src/main/java/org/onlab/util/SlidingWindowCounter.java b/utils/misc/src/main/java/org/onlab/util/SlidingWindowCounter.java
index cc4f4fe..d68cd74 100644
--- a/utils/misc/src/main/java/org/onlab/util/SlidingWindowCounter.java
+++ b/utils/misc/src/main/java/org/onlab/util/SlidingWindowCounter.java
@@ -190,12 +190,12 @@
}
void advanceHead() {
- if (counters.size() - 1 < slotAfter(headSlot)) {
- counters.add(0, new AtomicLong(0));
+ if (counters.size() < windowSlots) {
+ counters.add(new AtomicLong(0));
} else {
counters.get(slotAfter(headSlot)).set(0);
- headSlot = slotAfter(headSlot);
}
+ headSlot = slotAfter(headSlot);
totalSlots.incrementAndGet();
}
diff --git a/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java b/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java
index 039b1ff..d8289b0 100644
--- a/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java
+++ b/utils/misc/src/test/java/org/onlab/util/SlidingWindowCounterTest.java
@@ -77,6 +77,79 @@
}
@Test
+ public void testSlidingWindowStats() {
+ SlidingWindowCounter counter = new SlidingWindowCounter(3);
+
+ // 1
+ counter.incrementCount(1);
+ assertEquals(1, counter.getWindowCount());
+ assertEquals(1, counter.getWindowCount(1));
+
+ // 0, 1
+ counter.advanceHead();
+ assertEquals(1, counter.getWindowCount());
+ assertEquals(0, counter.getWindowCount(1));
+ assertEquals(1, counter.getWindowCount(2));
+
+ // 2, 1
+ counter.incrementCount(2);
+ assertEquals(3, counter.getWindowCount());
+ assertEquals(2, counter.getWindowCount(1));
+ assertEquals(3, counter.getWindowCount(2));
+
+ // 0, 2, 1
+ counter.advanceHead();
+ assertEquals(3, counter.getWindowCount());
+ assertEquals(0, counter.getWindowCount(1));
+ assertEquals(2, counter.getWindowCount(2));
+ assertEquals(3, counter.getWindowCount(3));
+
+ // 3, 2, 1
+ counter.incrementCount(3);
+ assertEquals(6, counter.getWindowCount());
+ assertEquals(3, counter.getWindowCount(1));
+ assertEquals(5, counter.getWindowCount(2));
+ assertEquals(6, counter.getWindowCount(3));
+
+ // 0, 3, 2
+ counter.advanceHead();
+ assertEquals(5, counter.getWindowCount());
+ assertEquals(0, counter.getWindowCount(1));
+ assertEquals(3, counter.getWindowCount(2));
+ assertEquals(5, counter.getWindowCount(3));
+
+ // 4, 3, 2
+ counter.incrementCount(4);
+ assertEquals(9, counter.getWindowCount());
+ assertEquals(4, counter.getWindowCount(1));
+ assertEquals(7, counter.getWindowCount(2));
+ assertEquals(9, counter.getWindowCount(3));
+
+ // 0, 4, 3
+ counter.advanceHead();
+ assertEquals(7, counter.getWindowCount());
+ assertEquals(0, counter.getWindowCount(1));
+ assertEquals(4, counter.getWindowCount(2));
+ assertEquals(7, counter.getWindowCount(3));
+
+ // 5, 4, 3
+ counter.incrementCount(5);
+ assertEquals(12, counter.getWindowCount());
+ assertEquals(5, counter.getWindowCount(1));
+ assertEquals(9, counter.getWindowCount(2));
+ assertEquals(12, counter.getWindowCount(3));
+
+ // 0, 5, 4
+ counter.advanceHead();
+ assertEquals(9, counter.getWindowCount());
+ assertEquals(0, counter.getWindowCount(1));
+ assertEquals(5, counter.getWindowCount(2));
+ assertEquals(9, counter.getWindowCount(3));
+
+ counter.destroy();
+ }
+
+ @Test
public void testRates() {
assertEquals(0, counter.getWindowRate(), 0.01);
assertEquals(0, counter.getOverallRate(), 0.01);