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);