Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 package org.ros.concurrent;
00018
00019 import java.util.Iterator;
00020 import java.util.NoSuchElementException;
00021
00029 public class CircularBlockingDeque<T> implements Iterable<T> {
00030
00031 private final T[] deque;
00032 private final Object mutex;
00033
00037 private final int limit;
00038
00043 private int start;
00044
00048 private int length;
00049
00054 @SuppressWarnings("unchecked")
00055 public CircularBlockingDeque(int capacity) {
00056 deque = (T[]) new Object[capacity];
00057 mutex = new Object();
00058 limit = capacity;
00059 start = 0;
00060 length = 0;
00061 }
00062
00071 public boolean addLast(T entry) {
00072 synchronized (mutex) {
00073 deque[(start + length) % limit] = entry;
00074 if (length == limit) {
00075 start = (start + 1) % limit;
00076 } else {
00077 length++;
00078 }
00079 mutex.notify();
00080 }
00081 return true;
00082 }
00083
00092 public boolean addFirst(T entry) {
00093 synchronized (mutex) {
00094 if (start - 1 < 0) {
00095 start = limit - 1;
00096 } else {
00097 start--;
00098 }
00099 deque[start] = entry;
00100 if (length < limit) {
00101 length++;
00102 }
00103 mutex.notify();
00104 }
00105 return true;
00106 }
00107
00115 public T takeFirst() throws InterruptedException {
00116 T entry;
00117 synchronized (mutex) {
00118 while (true) {
00119 if (length > 0) {
00120 entry = deque[start];
00121 start = (start + 1) % limit;
00122 length--;
00123 break;
00124 }
00125 mutex.wait();
00126 }
00127 }
00128 return entry;
00129 }
00130
00137 public T peekFirst() {
00138 synchronized (mutex) {
00139 if (length > 0) {
00140 return deque[start];
00141 }
00142 return null;
00143 }
00144 }
00145
00153 public T takeLast() throws InterruptedException {
00154 T entry;
00155 synchronized (mutex) {
00156 while (true) {
00157 if (length > 0) {
00158 entry = deque[(start + length - 1) % limit];
00159 length--;
00160 break;
00161 }
00162 mutex.wait();
00163 }
00164 }
00165 return entry;
00166 }
00167
00174 public T peekLast() {
00175 synchronized (mutex) {
00176 if (length > 0) {
00177 return deque[(start + length - 1) % limit];
00178 }
00179 return null;
00180 }
00181 }
00182
00183 public boolean isEmpty() {
00184 return length == 0;
00185 }
00186
00195 @Override
00196 public Iterator<T> iterator() {
00197 return new Iterator<T>() {
00198 int offset = 0;
00199
00200 @Override
00201 public boolean hasNext() {
00202 return offset < length;
00203 }
00204
00205 @Override
00206 public T next() {
00207 if (offset == length) {
00208 throw new NoSuchElementException();
00209 }
00210 T entry = deque[(start + offset) % limit];
00211 offset++;
00212 return entry;
00213 }
00214
00215 @Override
00216 public void remove() {
00217 throw new UnsupportedOperationException();
00218 }
00219 };
00220 }
00221 }