View Javadoc
1   package au.gov.amsa.util;
2   
3   import java.util.Collection;
4   import java.util.Iterator;
5   import java.util.NoSuchElementException;
6   import java.util.Queue;
7   
8   import net.jcip.annotations.NotThreadSafe;
9   
10  /**
11   * Non-threadsafe implementation of a Ring Buffer. Does not accept nulls.
12   * 
13   * @param <T>
14   */
15  @NotThreadSafe
16  public class RingBuffer<T> implements Queue<T> {
17  
18      private final T[] list;
19      private int start;
20      private int finish;
21  
22      @SuppressWarnings("unchecked")
23      private RingBuffer(int size) {
24          list = (T[]) new Object[size + 1];
25      }
26  
27      public static <T> RingBuffer<T> create(int size) {
28          return new RingBuffer<T>(size);
29      }
30  
31      @Override
32      public void clear() {
33          finish = start;
34      }
35  
36      @Override
37      public Iterator<T> iterator() {
38          final int _start = start;
39          final int _finish = finish;
40          return new Iterator<T>() {
41              int i = _start;
42  
43              @Override
44              public boolean hasNext() {
45                  return i != _finish;
46              }
47  
48              @Override
49              public T next() {
50                  T value = list[i];
51                  i = (i + 1) % list.length;
52                  return value;
53              }
54          };
55      }
56  
57      @Override
58      public T peek() {
59          if (start == finish)
60              return null;
61          else
62              return list[start];
63      }
64  
65      public boolean isEmpty() {
66          return start == finish;
67      }
68  
69      public int size() {
70          if (start <= finish)
71              return finish - start;
72          else
73              return finish - start + list.length;
74      }
75  
76      public int maxSize() {
77          return list.length - 1;
78      }
79  
80      @Override
81      public boolean contains(Object o) {
82          return notImplemented();
83      }
84  
85      @Override
86      public Object[] toArray() {
87          return notImplemented();
88      }
89  
90      @Override
91      public <S> S[] toArray(S[] a) {
92          return notImplemented();
93      }
94  
95      @Override
96      public boolean remove(Object o) {
97          return notImplemented();
98      }
99  
100     @Override
101     public boolean containsAll(Collection<?> c) {
102         return notImplemented();
103     }
104 
105     private static <T> T notImplemented() {
106         throw new RuntimeException("Not implemented");
107     }
108 
109     @Override
110     public boolean addAll(Collection<? extends T> c) {
111         for (T t : c)
112             add(t);
113         return true;
114     }
115 
116     @Override
117     public boolean removeAll(Collection<?> c) {
118         return notImplemented();
119     }
120 
121     @Override
122     public boolean retainAll(Collection<?> c) {
123         return notImplemented();
124     }
125 
126     @Override
127     public boolean add(T t) {
128         if (offer(t))
129             return true;
130         else
131             throw new IllegalStateException("Cannot add to queue because is full");
132     }
133 
134     @Override
135     public boolean offer(T t) {
136         if (t == null)
137             throw new NullPointerException();
138         int currentFinish = finish;
139         finish = (finish + 1) % list.length;
140         if (finish == start) {
141             return false;
142         } else {
143             list[currentFinish] = t;
144             return true;
145         }
146     }
147 
148     @Override
149     public T remove() {
150         T t = poll();
151         if (t == null)
152             throw new NoSuchElementException();
153         else
154             return t;
155     }
156 
157     @Override
158     public T poll() {
159         if (start == finish) {
160             return null;
161         } else {
162             T value = list[start];
163             // don't hold a reference to a popped value
164             list[start] = null;
165             start = (start + 1) % list.length;
166             return value;
167         }
168     }
169 
170     @Override
171     public T element() {
172         return notImplemented();
173     }
174 }