/*
* 作成日: 2009/04/22
*/
package jp.ac.fit.asura.nao.misc;
import jp.ac.fit.asura.nao.FrameContext;
/**
* @author sey
*
* @version $Id: $
*
*/
public class FrameQueue<T extends FrameContext> {
private T[] array;
private int capacity;
private int size;
private int lower;
private int upper;
/**
*
*/
public FrameQueue(int capacity) {
array = (T[]) new FrameContext[capacity * 2];
lower = 0;
upper = 0;
size = 0;
this.capacity = capacity;
}
public T findNearest(long keyTime) {
assert lower >= 0;
assert upper <= array.length;
assert upper >= lower;
assert upper - lower == size;
if (size == 0)
return null;
int low = lower;
int high = upper - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
int cmp = (int) (array[mid].getTime() - keyTime);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else {
// key found
return array[mid];
}
}
// key not found.
if (low == lower)
return array[low];
if (low == upper)
return array[low - 1];
if (keyTime - array[low - 1].getTime() > array[low].getTime() - keyTime)
return array[low];
else
return array[low - 1];
}
public T enqueue(T obj) {
assert lower >= 0;
assert upper <= array.length;
assert upper >= lower;
assert upper - lower == size;
assert upper == 0 || array[upper - 1].getTime() < obj.getTime() : array[upper - 1]
.getTime()
+ ":" + obj.getTime();
if (upper == array.length) {
upper -= lower;
for (int i = 0; i < upper; i++) {
array[i] = array[lower + i];
}
lower = 0;
}
// 先頭の1要素分むだになる?
array[upper++] = obj;
if (size == capacity) {
lower++;
return array[lower - 1];
} else {
size++;
return null;
}
}
public T dequeue() {
if (size == 0)
return null;
size--;
return array[lower++];
}
}