1d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy/* 2d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * Copyright (C) 2009 The Android Open Source Project 3d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * 4d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * you may not use this file except in compliance with the License. 6d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * You may obtain a copy of the License at 7d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * 8d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 9d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * 10d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * Unless required by applicable law or agreed to in writing, software 11d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * See the License for the specific language governing permissions and 14d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * limitations under the License. 15d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy */ 16d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy 17d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guypackage android.util; 18d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy 19d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy/** 20abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * Helper class for crating pools of objects. An example use looks like this: 21abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * <pre> 22abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * public class MyPooledClass { 23abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 24be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov * private static final SynchronizedPool<MyPooledClass> sPool = 25be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov * new SynchronizedPool<MyPooledClass>(10); 26abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 27abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * public static MyPooledClass obtain() { 28abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * MyPooledClass instance = sPool.acquire(); 29abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * return (instance != null) ? instance : new MyPooledClass(); 30abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * } 31abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 32abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * public void recycle() { 33abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * // Clear state if needed. 34abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * sPool.release(this); 35abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * } 36abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 37abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * . . . 38abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * } 39abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * </pre> 40abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 41d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy * @hide 42d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy */ 43abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganovpublic final class Pools { 44abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 45abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov /** 46abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * Interface for managing a pool of objects. 47abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 48abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @param <T> The pooled type. 49abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov */ 50abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public static interface Pool<T> { 51abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 52abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov /** 53abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @return An instance from the pool if such, null otherwise. 54abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov */ 55abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public T acquire(); 56abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 57abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov /** 58abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * Release an instance to the pool. 59abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 60abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @param instance The instance to release. 61abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @return Whether the instance was put in the pool. 62abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 63abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @throws IllegalStateException If the instance is already in the pool. 64abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov */ 65abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public boolean release(T instance); 66d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy } 67d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy 68abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov private Pools() { 69abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov /* do nothing - hiding constructor */ 70d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy } 71abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 72abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov /** 73abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * Simple (non-synchronized) pool of objects. 74abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 75abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @param <T> The pooled type. 76abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov */ 77abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public static class SimplePool<T> implements Pool<T> { 7860fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov private final Object[] mPool; 79abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 80abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov private int mPoolSize; 81abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 82abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov /** 83abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * Creates a new instance. 84abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 85abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @param maxPoolSize The max pool size. 86abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 87abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @throws IllegalArgumentException If the max pool size is less than zero. 88abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov */ 89abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public SimplePool(int maxPoolSize) { 90be922dc976b1ce1735dcc0cf49509a2149766c96Svetoslav Ganov if (maxPoolSize <= 0) { 91abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov throw new IllegalArgumentException("The max pool size must be > 0"); 92abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 9360fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov mPool = new Object[maxPoolSize]; 94abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 95abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 96abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov @Override 9760fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov @SuppressWarnings("unchecked") 98abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public T acquire() { 9960fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov if (mPoolSize > 0) { 10060fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov final int lastPooledIndex = mPoolSize - 1; 10160fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov T instance = (T) mPool[lastPooledIndex]; 10260fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov mPool[lastPooledIndex] = null; 103abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov mPoolSize--; 10460fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov return instance; 105abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 106abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov return null; 107abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 108abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 109abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov @Override 110abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public boolean release(T instance) { 111abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov if (isInPool(instance)) { 112abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov throw new IllegalStateException("Already in the pool!"); 113abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 11460fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov if (mPoolSize < mPool.length) { 11560fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov mPool[mPoolSize] = instance; 116abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov mPoolSize++; 117abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov return true; 118abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 119abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov return false; 120abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 121abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 122abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov private boolean isInPool(T instance) { 12360fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov for (int i = 0; i < mPoolSize; i++) { 12460fba77035ba02b211e352dc1fbbafcbe3583b46Svetoslav Ganov if (mPool[i] == instance) { 125abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov return true; 126abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 127abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 128abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov return false; 129abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 130d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy } 131d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy 132abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov /** 133abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * Synchronized) pool of objects. 134abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 135abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @param <T> The pooled type. 136abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov */ 137abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public static class SynchronizedPool<T> extends SimplePool<T> { 138abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov private final Object mLock = new Object(); 139abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 140abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov /** 141abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * Creates a new instance. 142abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 143abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @param maxPoolSize The max pool size. 144abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * 145abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov * @throws IllegalArgumentException If the max pool size is less than zero. 146abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov */ 147abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public SynchronizedPool(int maxPoolSize) { 148abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov super(maxPoolSize); 149abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 150abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 151abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov @Override 152abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public T acquire() { 153abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov synchronized (mLock) { 154abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov return super.acquire(); 155abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 156abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 157abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov 158abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov @Override 159abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov public boolean release(T element) { 160abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov synchronized (mLock) { 161abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov return super.release(element); 162abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 163abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov } 164d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy } 165d1b3dd058d2015cd1f2a3ef7fb3798f0d7923fe3Romain Guy} 166