diff options
author | Travis Watkins <amaranth@ubuntu.com> | 2012-08-19 19:59:58 -0500 |
---|---|---|
committer | Travis Watkins <amaranth@ubuntu.com> | 2012-08-20 18:44:07 -0500 |
commit | ccc760d629e657e3b349ac9ea7abd890b4592106 (patch) | |
tree | 69c6044550ab65eda50e0b7471acf30da1298990 /src/main | |
parent | e7e643d83a137107727d2120e51a2ee3ad571d1a (diff) | |
download | craftbukkit-ccc760d629e657e3b349ac9ea7abd890b4592106.tar craftbukkit-ccc760d629e657e3b349ac9ea7abd890b4592106.tar.gz craftbukkit-ccc760d629e657e3b349ac9ea7abd890b4592106.tar.lz craftbukkit-ccc760d629e657e3b349ac9ea7abd890b4592106.tar.xz craftbukkit-ccc760d629e657e3b349ac9ea7abd890b4592106.zip |
Use a dynamic pool size for the iterator cache
Many codepaths only end up with one iterator being used at a time and
most of the rest only get up to two being used so using a static pool of
three is wasteful. This also allows us to efficiently handle cases that
exceed 3 iterators in use. Overall this dramatically increases the hit rate
and results in less iterators being created.
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/java/net/minecraft/server/PathfinderGoalSelector.java | 2 | ||||
-rw-r--r-- | src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java | 56 |
2 files changed, 37 insertions, 21 deletions
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java index 02f6e46b..38f53522 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalSelector.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalSelector.java @@ -111,11 +111,13 @@ public class PathfinderGoalSelector { // CraftBukkit - switch order if (!this.a(pathfindergoalselectoritem, pathfindergoalselectoritem1) && this.b.contains(pathfindergoalselectoritem1)) { // this.c.b(); // CraftBukkit - not in production code + ((UnsafeList.Itr) iterator).valid = false; // CraftBukkit - mark iterator for reuse return false; } // CraftBukkit - switch order } else if (!pathfindergoalselectoritem1.a.g() && this.b.contains(pathfindergoalselectoritem1)) { // this.c.b(); // CraftBukkit - not in production code + ((UnsafeList.Itr) iterator).valid = false; // CraftBukkit - mark iterator for reuse return false; } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java index b1e3416d..1351ecd8 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java +++ b/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java @@ -14,25 +14,28 @@ import java.util.RandomAccess; // implementation of an ArrayList that offers a getter without range checks @SuppressWarnings("unchecked") public class UnsafeList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable { - private static final long serialVersionUID = 8683452581112892190L; + private static final long serialVersionUID = 8683452581112892191L; private transient Object[] data; private int size; private int initialCapacity; - private Iterator[] iterPool = new Iterator[3]; + private Iterator[] iterPool = new Iterator[1]; + private int maxPool; private int poolCounter; - public UnsafeList(int capacity) { + 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(); + } - for (int i = 0; i < iterPool.length; i++) { - iterPool[i] = new Itr(); - } + public UnsafeList(int capacity) { + this(capacity, 5); } public UnsafeList() { @@ -143,31 +146,38 @@ public class UnsafeList<E> extends AbstractList<E> implements List<E>, RandomAcc copy.data = Java15Compat.Arrays_copyOf(data, size); copy.size = size; copy.initialCapacity = initialCapacity; - copy.iterPool = new Iterator[iterPool.length]; + copy.iterPool = new Iterator[1]; + copy.iterPool[0] = new Itr(); + copy.maxPool = maxPool; + copy.poolCounter = 0; return copy; } public Iterator<E> iterator() { - Itr iterator = null; - poolCounter = poolCounter++ % iterPool.length; - // Try to find an iterator that isn't in use for (Iterator iter : iterPool) { if (!((Itr) iter).valid) { - iterator = (Itr) iter; - break; + Itr iterator = (Itr) iter; + iterator.reset(); + return iterator; } } - // 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 - if (iterator == null) { - iterPool[poolCounter] = new Itr(); - iterator = (Itr) iterPool[poolCounter]; + // 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]; } - iterator.reset(); - return iterator; + // 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) { @@ -192,6 +202,7 @@ public class UnsafeList<E> extends AbstractList<E> implements List<E>, RandomAcc for (int i = 0; i < size; i++) { os.writeObject(data[i]); } + os.writeInt(maxPool); } private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException { @@ -203,13 +214,16 @@ public class UnsafeList<E> extends AbstractList<E> implements List<E>, RandomAcc for (int i = 0; i < size; i++) { data[i] = is.readObject(); } + maxPool = is.readInt(); + iterPool = new Iterator[1]; + iterPool[0] = new Itr(); } - private class Itr implements Iterator<E> { + public class Itr implements Iterator<E> { int index; int lastRet = -1; int expectedModCount = modCount; - boolean valid = true; + public boolean valid = true; public void reset() { index = 0; |