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