package com.codahale.metrics;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongArray;

import static java.lang.Math.min;

/**
 * A {@link Reservoir} implementation backed by a sliding window that stores the last {@code N}
 * measurements.
 */
public class SlidingWindowReservoir implements Reservoir {
    private final AtomicLongArray measurements;
    private final AtomicLong count;
    private final AtomicLong sequence;

    /**
     * Creates a new {@link SlidingWindowReservoir} which stores the last {@code size} measurements.
     *
     * @param size the number of measurements to store
     */
    public SlidingWindowReservoir(int size) {
        this.measurements = new AtomicLongArray(size);
        this.count = new AtomicLong();
        this.sequence = new AtomicLong();
    }

    @Override
    public int size() {
        return (int) min(count.get(), measurements.length());
    }

    @Override
    public void update(long value) {
        final int i = (int) (count.getAndIncrement() % measurements.length());
        measurements.set(i, value);
        sequence.incrementAndGet();
    }

    @Override
    public Snapshot getSnapshot() {
        while(count.get() != sequence.get()) {
            Thread.yield();
        }

        final long[] values = new long[size()];
        for (int i = 0; i < values.length; i++) {
            values[i] = measurements.get(i);
        }
        return new Snapshot(values);
    }
}

@@ -28,108 +28,8 @@
 s;%0A%0A
-import java.util.concurrent.atomic.AtomicLong;%0Aimport java.util.concurrent.atomic.AtomicLongArray;%0A%0A
 impo
@@ -257,31 +257,22 @@
 e final 
-AtomicLongArray
+long%5B%5D
  measure
@@ -294,69 +294,18 @@
 ate 
-final AtomicLong count;%0A    private final AtomicLong sequence
+long count
 ;%0A%0A 
@@ -564,29 +564,18 @@
 new 
-AtomicLongArray(
+long%5B
 size
-)
+%5D
 ;%0A  
@@ -597,66 +597,9 @@
 t = 
-new AtomicLong();%0A        this.sequence = new AtomicLong()
+0
 ;%0A  
@@ -628,16 +628,29 @@
  public 
+synchronized 
 int size
@@ -684,22 +684,16 @@
 in(count
-.get()
 , measur
@@ -701,26 +701,24 @@
 ments.length
-()
 );%0A    %7D%0A%0A  
@@ -740,16 +740,29 @@
  public 
+synchronized 
 void upd
@@ -791,52 +791,35 @@
     
-final int i = 
+measurements%5B(
 (int) 
-(
 count
-.getAndIncrement()
+++
  %25 m
@@ -840,227 +840,76 @@
 ngth
-());%0A        measurements.set(i, value);%0A        sequence.incrementAndGet();%0A    %7D%0A%0A    @Override%0A    public Snapshot getSnapshot() %7B%0A        while(count.get() != sequence.get()) %7B%0A            Thread.yield();%0A        %7D%0A
+)%5D = value;%0A    %7D%0A%0A    @Override%0A    public Snapshot getSnapshot() %7B
 %0A   
@@ -999,24 +999,62 @@
 gth; i++) %7B%0A
+            synchronized (this) %7B%0A    
             
@@ -1081,16 +1081,26 @@
 ents
-.get(i);
+%5Bi%5D;%0A            %7D
 %0A   

Make SlidingWindowReservoir synchronized.