package com.foursquare.heapaudit;
import java.util.AbstractCollection;
import java.util.Iterator;
// This is a poor man's implementation of a collection library intended for
// internal usage only. The following does not implement the full interface of a
// typical collection and is not thread safe. The main reason for using this
// internal collection as oppose to ArrayList is to avoid the circular
// dependency of the HeapAudit instrumentation on ArrayList while Arraylist is
// also being instrumented by HeapAudit. Otherwise, an infinite recursion will
// occur during the instrumentation phase.
public class HeapCollection<E> extends AbstractCollection<E> {
private Object[] objects;
private int size;
private int index;
public HeapCollection() {
objects = new Object[64];
size = 0;
index = 0;
}
public boolean add(E e) {
if (size == objects.length) {
Object[] collection = new Object[size * 2];
System.arraycopy(objects,
0,
collection,
0,
size);
objects = collection;
}
else if (size < index) {
for (int i = 0; i < index; ++i) {
if (objects[i] == null) {
objects[i] = e;
++size;
break;
}
}
}
else {
objects[index] = e;
++size;
++index;
}
return true;
}
public boolean remove(Object e) {
for (int i = 0; i < index; ++i) {
if (e.equals(objects[i])) {
objects[i] = null;
--size;
if (i == index - 1) {
--index;
}
return true;
}
}
return false;
}
public int size() {
return size;
}
public Iterator<E> iterator() {
return new HeapIterator();
}
private class HeapIterator implements Iterator<E> {
private int cursor = -1;
private int count = HeapCollection.this.size;
public boolean hasNext() {
return count > 0;
}
public E next() {
while (objects[++cursor] == null);
--count;
return (E)objects[cursor];
}
public void remove() {
objects[cursor] = null;
--HeapCollection.this.size;
}
}
}