blob: bc109d0c4a231ce6e2609a55b58d87e3d70643ef [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and Others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Hideki TAI - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.util.internal.httpproxy.core;
import java.util.Comparator;
import org.eclipse.actf.util.httpproxy.core.TimeoutException;
public class FixedSizeQueue {
private Object[] fQueue;
private int fSize;
private int fNextIndex = 0;
private int fMinIndex = 0;
public FixedSizeQueue(int queueSize) {
fQueue = new Object[queueSize];
fSize = queueSize;
}
public int getQueueSize() {
return fSize;
}
public synchronized void clear() {
if (fMinIndex != fNextIndex) {
do {
fQueue[fMinIndex++] = null;
if (fMinIndex > fSize) {
fMinIndex = 0;
}
} while (fMinIndex != fNextIndex);
}
fNextIndex = 0;
fMinIndex = 0;
fQueue[0] = null;
}
public synchronized boolean isEmpty() {
return (fNextIndex == fMinIndex);
}
public synchronized int getSize() {
int d = fNextIndex - fMinIndex;
return (d >= 0) ? d : d + fSize;
}
public synchronized void put(Object obj) throws InterruptedException {
if (obj == null) {
throw new IllegalArgumentException("null");
}
while (fQueue[fNextIndex] != null) {
this.wait();
}
fQueue[fNextIndex++] = obj;
if (fNextIndex >= fSize) {
fNextIndex = 0;
}
this.notifyAll();
}
public synchronized void put(Object obj, long timeout) throws TimeoutException, InterruptedException {
if (timeout == 0) {
put(obj);
} else {
if (obj == null) {
throw new IllegalArgumentException("null");
}
if (fQueue[fNextIndex] != null) {
long t0 = System.currentTimeMillis();
long wait = timeout;
boolean timedout = true;
do {
this.wait(wait);
if (fQueue[fNextIndex] == null) {
timedout = false;
break;
}
long elapsed = System.currentTimeMillis() - t0;
wait = timeout - elapsed;
} while (wait > 0);
if (timedout) {
throw new TimeoutException("FixedSizeQueue.put");
}
}
fQueue[fNextIndex++] = obj;
if (fNextIndex >= fSize) {
fNextIndex = 0;
}
this.notifyAll();
}
}
public synchronized Object remove() throws InterruptedException {
Object req;
while ((req = fQueue[fMinIndex]) == null) {
this.wait();
}
fQueue[fMinIndex++] = null;
if (fMinIndex >= fSize) {
fMinIndex = 0;
}
this.notifyAll();
return req;
}
public synchronized Object remove(long timeout) throws TimeoutException, InterruptedException {
Object req = fQueue[fMinIndex];
if (req == null) {
long t0 = System.currentTimeMillis();
long wait = timeout;
do {
this.wait(wait);
if ((req = fQueue[fMinIndex]) != null) {
break;
}
long elapsed = System.currentTimeMillis() - t0;
wait = timeout - elapsed;
} while (wait > 0);
if (req == null) {
throw new TimeoutException("FixedSizeQueue.remove");
}
}
fQueue[fMinIndex++] = null;
if (fMinIndex >= fSize) {
fMinIndex = 0;
}
this.notifyAll();
return req;
}
public synchronized Object nonBlockingRemove() {
Object req = fQueue[fMinIndex];
if (req != null) {
fQueue[fMinIndex++] = null;
if (fMinIndex >= fSize) {
fMinIndex = 0;
}
this.notifyAll();
}
return req;
}
public synchronized Object matchAndRemove(Object o, Comparator comparator) {
if (o == null) {
throw new IllegalArgumentException();
}
Object req = fQueue[fMinIndex];
if (req == null) {
return null;
}
if (comparator.compare(o, req) == 0) {
fQueue[fMinIndex++] = null;
if (fMinIndex >= fSize) {
fMinIndex = 0;
}
this.notifyAll();
return req;
} else {
return null;
}
}
}