summaryrefslogtreecommitdiffstats
path: root/src/main/java/net/minecraft/server/Vec3DPool.java
diff options
context:
space:
mode:
authorMike Primm <mike@primmhome.com>2012-08-11 17:27:27 -0500
committerTravis Watkins <amaranth@ubuntu.com>2012-08-19 09:50:57 -0500
commit8219081385833a4f020fc5912e27a78da227e777 (patch)
tree3053f2d7b8310b1ff2bf37d24ec53e415974b8f5 /src/main/java/net/minecraft/server/Vec3DPool.java
parentd628c886d2c96c0bc8cd67bb3cd7cfba0b96f1a8 (diff)
downloadcraftbukkit-8219081385833a4f020fc5912e27a78da227e777.tar
craftbukkit-8219081385833a4f020fc5912e27a78da227e777.tar.gz
craftbukkit-8219081385833a4f020fc5912e27a78da227e777.tar.lz
craftbukkit-8219081385833a4f020fc5912e27a78da227e777.tar.xz
craftbukkit-8219081385833a4f020fc5912e27a78da227e777.zip
[Bleeding] Change Vec3DPool to a stack based pool
Avoid overhead of using an ArrayList and resizing it. Also allows for reuse of objects in the pool during the same tick by explicitly releasing them back to the pool. This allows for much better cache performance as well as reduced cache footprint.
Diffstat (limited to 'src/main/java/net/minecraft/server/Vec3DPool.java')
-rw-r--r--src/main/java/net/minecraft/server/Vec3DPool.java63
1 files changed, 54 insertions, 9 deletions
diff --git a/src/main/java/net/minecraft/server/Vec3DPool.java b/src/main/java/net/minecraft/server/Vec3DPool.java
index 33e21ef2..897fef93 100644
--- a/src/main/java/net/minecraft/server/Vec3DPool.java
+++ b/src/main/java/net/minecraft/server/Vec3DPool.java
@@ -7,7 +7,16 @@ public class Vec3DPool {
private final int a;
private final int b;
- private final List c = new ArrayList();
+ // CraftBukkit start
+ // private final List c = new ArrayList();
+ private Vec3D freelist = null;
+ private Vec3D alloclist = null;
+ private Vec3D freelisthead = null;
+ private Vec3D alloclisthead = null;
+ private int total_size = 0;
+ private int hit;
+ private int miss;
+ // CraftBukkit end
private int d = 0;
private int e = 0;
private int f = 0;
@@ -17,21 +26,44 @@ public class Vec3DPool {
this.b = j;
}
- public Vec3D create(double d0, double d1, double d2) {
+ public final Vec3D create(double d0, double d1, double d2) { // CraftBukkit - add final
if (this.f == 0) return new Vec3D(d0, d1, d2); // CraftBukkit - don't pool objects indefinitely if thread doesn't adhere to contract
Vec3D vec3d;
- if (this.d >= this.c.size()) {
+ if (this.freelist == null) { // CraftBukkit
vec3d = new Vec3D(d0, d1, d2);
- this.c.add(vec3d);
+ this.total_size++; // CraftBukkit
} else {
- vec3d = (Vec3D) this.c.get(this.d);
+ // CraftBukkit start
+ vec3d = this.freelist;
+ this.freelist = vec3d.next;
+ // CraftBukkit end
vec3d.b(d0, d1, d2);
}
+ // CraftBukkit start
+ if (this.alloclist == null) {
+ this.alloclisthead = vec3d;
+ }
+ vec3d.next = this.alloclist; // add to allocated list
+ this.alloclist = vec3d;
+ // CraftBukkit end
++this.d;
return vec3d;
}
+
+ // CraftBukkit start - offer back vector (can save LOTS of unneeded bloat) - works about 90% of the time
+ public void release(Vec3D v) {
+ if (this.alloclist == v) {
+ this.alloclist = v.next; // Pop off alloc list
+ // Push on to free list
+ if (this.freelist == null) this.freelisthead = v;
+ v.next = this.freelist;
+ this.freelist = v;
+ this.d--;
+ }
+ }
+ // CraftBukkit end
public void a() {
if (this.d > this.e) {
@@ -39,14 +71,27 @@ public class Vec3DPool {
}
// CraftBukkit start - intelligent cache
+ // Take any allocated blocks and put them on free list
+ if (this.alloclist != null) {
+ if (this.freelist == null) {
+ this.freelist = this.alloclist;
+ this.freelisthead = this.alloclisthead;
+ }
+ else {
+ this.alloclisthead.next = this.freelist;
+ this.freelist = this.alloclist;
+ this.freelisthead = this.alloclisthead;
+ }
+ this.alloclist = null;
+ }
if ((this.f++ & 0xff) == 0) {
- int newSize = this.c.size() - (this.c.size() >> 3);
+ int newSize = total_size - (total_size >> 3);
if (newSize > this.e) { // newSize will be 87.5%, but if we were not in that range, we clear some of the cache
- for (int i = this.c.size() - 1; i > newSize; i--) { // Work down from size() to prevent insane array copies
- this.c.remove(i);
+ for (int i = total_size; i > newSize; i--) {
+ freelist = freelist.next;
}
+ total_size = newSize;
}
-
this.e = 0;
// this.f = 0; // We do not reset to zero; it doubles for a flag
}