From fe08b9d9bdc6c775570bfa68cc9bb5a24fc8cf31 Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 24 Sep 2014 01:58:50 +0200 Subject: [PATCH] Fixed classpath. Added a REALLY Fast ObjectPool --- Dorkbox-Util/.classpath | 2 +- Dorkbox-Util/LICENSE.TXT | 15 +- .../src/dorkbox/util/FastObjectPool.java | 167 ++++++++++++++++++ 3 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 Dorkbox-Util/src/dorkbox/util/FastObjectPool.java diff --git a/Dorkbox-Util/.classpath b/Dorkbox-Util/.classpath index e3ce5ef..d12e36d 100644 --- a/Dorkbox-Util/.classpath +++ b/Dorkbox-Util/.classpath @@ -2,7 +2,6 @@ - @@ -24,5 +23,6 @@ + diff --git a/Dorkbox-Util/LICENSE.TXT b/Dorkbox-Util/LICENSE.TXT index f99039f..f5a05ec 100644 --- a/Dorkbox-Util/LICENSE.TXT +++ b/Dorkbox-Util/LICENSE.TXT @@ -76,7 +76,14 @@ Legal: - BouncyCastle - MIT X11 License http://www.bouncycastle.org - Copyright (c) 2000 - 2009 The Legion Of The Bouncy Castle + Copyright 2000 - 2009 The Legion Of The Bouncy Castle + + + + - FastObjectPool - Apache 2.0 license + http://ashkrit.blogspot.com/2013/05/lock-less-java-object-pool.html + https://github.com/ashkrit/blog/tree/master/FastObjectPool + Copyright 2013 Ashkrit @@ -88,7 +95,7 @@ Legal: - MathUtils, IntArray, IntMap - Apache 2.0 license http://github.com/libgdx/libgdx/ - Copyright (c) 2013 + Copyright 2013 Mario Zechner Nathan Sweet @@ -96,5 +103,5 @@ Legal: - MersenneTwisterFast, v20 - BSD license http://www.cs.gmu.edu/~sean/research/mersenne/MersenneTwisterFast.java - Copyright (c) 2003 by Sean Luke. - Portions copyright (c) 1993 by Michael Lecuyer. + Copyright 2003 by Sean Luke + Portions copyright 1993 by Michael Lecuyer diff --git a/Dorkbox-Util/src/dorkbox/util/FastObjectPool.java b/Dorkbox-Util/src/dorkbox/util/FastObjectPool.java new file mode 100644 index 0000000..e1c003e --- /dev/null +++ b/Dorkbox-Util/src/dorkbox/util/FastObjectPool.java @@ -0,0 +1,167 @@ +package dorkbox.util; + +/* + * + * from: http://ashkrit.blogspot.de/2013/05/lock-less-java-object-pool.html + * https://github.com/ashkrit/blog/tree/master/FastObjectPool + * copyright ashkrit 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.lang.reflect.Field; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; + +import sun.misc.Unsafe; + + +public class FastObjectPool { + + private Holder[] objects; + + private volatile int takePointer; + private int releasePointer; + + private final int mask; + private final long BASE; + private final long INDEXSCALE; + private final long ASHIFT; + + public ReentrantLock lock = new ReentrantLock(); + private ThreadLocal> localValue = new ThreadLocal<>(); + + @SuppressWarnings("unchecked") + public FastObjectPool(PoolFactory factory , int size) + { + + int newSize=1; + while(newSize(factory.create()); + } + this.mask = size-1; + this.releasePointer = size; + this.BASE = THE_UNSAFE.arrayBaseOffset(Holder[].class); + this.INDEXSCALE = THE_UNSAFE.arrayIndexScale(Holder[].class); + this.ASHIFT = 31 - Integer.numberOfLeadingZeros((int) this.INDEXSCALE); + } + + public Holder take() + { + int localTakePointer; + + Holder localObject = this.localValue.get(); + if(localObject!=null) + { + if(localObject.state.compareAndSet(Holder.FREE, Holder.USED)) + { + return localObject; + } + } + + while(this.releasePointer != (localTakePointer=this.takePointer) ) + { + int index = localTakePointer & this.mask; + Holder holder = this.objects[index]; + //if(holder!=null && THE_UNSAFE.compareAndSwapObject(objects, (index*INDEXSCALE)+BASE, holder, null)) + if(holder!=null && THE_UNSAFE.compareAndSwapObject(this.objects, (index< object) throws InterruptedException + { + this.lock.lockInterruptibly(); + try{ + int localValue=this.releasePointer; + //long index = ((localValue & mask) * INDEXSCALE ) + BASE; + long index = ((localValue & this.mask)< + { + private T value; + public static final int FREE=0; + public static final int USED=1; + + private AtomicInteger state = new AtomicInteger(FREE); + public Holder(T value) + { + this.value = value; + } + + public T getValue() { + return this.value; + } + } + + public static interface PoolFactory + { + public T create(); + } + + public static final Unsafe THE_UNSAFE; + static + { + try + { + final PrivilegedExceptionAction action = new PrivilegedExceptionAction() + { + @Override + public Unsafe run() throws Exception + { + Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + return (Unsafe) theUnsafe.get(null); + } + }; + + THE_UNSAFE = AccessController.doPrivileged(action); + } + catch (Exception e) + { + throw new RuntimeException("Unable to load unsafe", e); + } + } +} \ No newline at end of file