
org.bukkit.craftbukkit.util.UnsafeList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of walk-server Show documentation
Show all versions of walk-server Show documentation
A spigot fork to kotlin structure and news.
package org.bukkit.craftbukkit.util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.*;
// implementation of an ArrayList that offers a getter without range checks
@SuppressWarnings("unchecked")
public class UnsafeList extends AbstractList implements List, RandomAccess, Cloneable, Serializable {
private static final long serialVersionUID = 8683452581112892191L;
private transient Object[] data;
private int size;
private int initialCapacity;
private Iterator[] iterPool = new Iterator[1];
private int maxPool;
private int poolCounter;
public UnsafeList(int capacity, int maxIterPool) {
super();
if (capacity < 0) capacity = 32;
int rounded = Integer.highestOneBit(capacity - 1) << 1;
data = new Object[rounded];
initialCapacity = rounded;
maxPool = maxIterPool;
iterPool[0] = new Itr();
}
public UnsafeList(int capacity) {
this(capacity, 5);
}
public UnsafeList() {
this(32);
}
public E get(int index) {
rangeCheck(index);
return (E) data[index];
}
public E unsafeGet(int index) {
return (E) data[index];
}
public E set(int index, E element) {
rangeCheck(index);
E old = (E) data[index];
data[index] = element;
return old;
}
public boolean add(E element) {
growIfNeeded();
data[size++] = element;
return true;
}
public void add(int index, E element) {
growIfNeeded();
System.arraycopy(data, index, data, index + 1, size - index);
data[index] = element;
size++;
}
public E remove(int index) {
rangeCheck(index);
E old = (E) data[index];
int movedCount = size - index - 1;
if (movedCount > 0) {
System.arraycopy(data, index + 1, data, index, movedCount);
}
data[--size] = null;
return old;
}
public boolean remove(Object o) {
int index = indexOf(o);
if (index >= 0) {
remove(index);
return true;
}
return false;
}
public int indexOf(Object o) {
for (int i = 0; i < size; i++) {
if (o == data[i] || o.equals(data[i])) {
return i;
}
}
return -1;
}
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public void clear() {
// Create new array to reset memory usage to initial capacity
size = 0;
// If array has grown too large create new one, otherwise just clear it
if (data.length > initialCapacity << 3) {
data = new Object[initialCapacity];
} else {
for (int i = 0; i < data.length; i++) {
data[i] = null;
}
}
}
// actually rounds up to nearest power of two
public void trimToSize() {
int old = data.length;
int rounded = Integer.highestOneBit(size - 1) << 1;
if (rounded < old) {
data = Arrays.copyOf(data, rounded);
}
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public Object clone() throws CloneNotSupportedException {
UnsafeList copy = (UnsafeList) super.clone();
copy.data = Arrays.copyOf(data, size);
copy.size = size;
copy.initialCapacity = initialCapacity;
copy.iterPool = new Iterator[1];
copy.iterPool[0] = new Itr();
copy.maxPool = maxPool;
copy.poolCounter = 0;
return copy;
}
public Iterator iterator() {
// Try to find an iterator that isn't in use
for (Iterator iter : iterPool) {
if (!((Itr) iter).valid) {
Itr iterator = (Itr) iter;
iterator.reset();
return iterator;
}
}
// Couldn't find one, see if we can grow our pool size
if (iterPool.length < maxPool) {
Iterator[] newPool = new Iterator[iterPool.length + 1];
System.arraycopy(iterPool, 0, newPool, 0, iterPool.length);
iterPool = newPool;
iterPool[iterPool.length - 1] = new Itr();
return iterPool[iterPool.length - 1];
}
// Still couldn't find a free one, round robin replace one with a new iterator
// This is done in the hope that the new one finishes so can be reused
poolCounter = ++poolCounter % iterPool.length;
iterPool[poolCounter] = new Itr();
return iterPool[poolCounter];
}
private void rangeCheck(int index) {
if (index >= size || index < 0) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
}
private void growIfNeeded() {
if (size == data.length) {
Object[] newData = new Object[data.length << 1];
System.arraycopy(data, 0, newData, 0, size);
data = newData;
}
}
private void writeObject(ObjectOutputStream os) throws IOException {
os.defaultWriteObject();
os.writeInt(size);
os.writeInt(initialCapacity);
for (int i = 0; i < size; i++) {
os.writeObject(data[i]);
}
os.writeInt(maxPool);
}
private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
is.defaultReadObject();
size = is.readInt();
initialCapacity = is.readInt();
data = new Object[Integer.highestOneBit(size - 1) << 1];
for (int i = 0; i < size; i++) {
data[i] = is.readObject();
}
maxPool = is.readInt();
iterPool = new Iterator[1];
iterPool[0] = new Itr();
}
public class Itr implements Iterator {
public boolean valid = true;
int index;
int lastRet = -1;
int expectedModCount = modCount;
public void reset() {
index = 0;
lastRet = -1;
expectedModCount = modCount;
valid = true;
}
public boolean hasNext() {
valid = index != size;
return valid;
}
public E next() {
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
int i = index;
if (i >= size) {
throw new NoSuchElementException();
}
if (i >= data.length) {
throw new ConcurrentModificationException();
}
index = i + 1;
return (E) data[lastRet = i];
}
public void remove() {
if (lastRet < 0) {
throw new IllegalStateException();
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
try {
UnsafeList.this.remove(lastRet);
index = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy