1009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell/* 2009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * Copyright (C) 2013 The Android Open Source Project 3009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 4009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * you may not use this file except in compliance with the License. 6009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * You may obtain a copy of the License at 7009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 8009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * http://www.apache.org/licenses/LICENSE-2.0 9009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 10009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * Unless required by applicable law or agreed to in writing, software 11009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * See the License for the specific language governing permissions and 14009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * limitations under the License. 15009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell */ 16009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 17009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 18009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powellpackage android.support.v4.util; 19009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 20009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 21009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell/** 226db4c676e03b3637cc0182ba5475d47e8be62c92Aurimas Liutikas * Helper class for creating pools of objects. An example use looks like this: 23009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * <pre> 24009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * public class MyPooledClass { 25009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 26009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * private static final SynchronizedPool<MyPooledClass> sPool = 27009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * new SynchronizedPool<MyPooledClass>(10); 28009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 29009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * public static MyPooledClass obtain() { 30009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * MyPooledClass instance = sPool.acquire(); 31009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * return (instance != null) ? instance : new MyPooledClass(); 32009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * } 33009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 34009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * public void recycle() { 35009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * // Clear state if needed. 36009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * sPool.release(this); 37009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * } 38009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 39009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * . . . 40009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * } 41009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * </pre> 42009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 43009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell */ 44009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powellpublic final class Pools { 45009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 46009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell /** 47009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * Interface for managing a pool of objects. 48009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 49009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @param <T> The pooled type. 50009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell */ 51009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public static interface Pool<T> { 52009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 53009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell /** 54009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @return An instance from the pool if such, null otherwise. 55009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell */ 56009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public T acquire(); 57009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 58009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell /** 59009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * Release an instance to the pool. 60009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 61009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @param instance The instance to release. 62009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @return Whether the instance was put in the pool. 63009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 64009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @throws IllegalStateException If the instance is already in the pool. 65009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell */ 66009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public boolean release(T instance); 67009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 68009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 69009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell private Pools() { 70009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell /* do nothing - hiding constructor */ 71009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 72009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 73009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell /** 74009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * Simple (non-synchronized) pool of objects. 75009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 76009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @param <T> The pooled type. 77009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell */ 78009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public static class SimplePool<T> implements Pool<T> { 79009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell private final Object[] mPool; 80009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 81009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell private int mPoolSize; 82009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 83009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell /** 84009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * Creates a new instance. 85009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 86009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @param maxPoolSize The max pool size. 87009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 88009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @throws IllegalArgumentException If the max pool size is less than zero. 89009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell */ 90009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public SimplePool(int maxPoolSize) { 91009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell if (maxPoolSize <= 0) { 92009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell throw new IllegalArgumentException("The max pool size must be > 0"); 93009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 94009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell mPool = new Object[maxPoolSize]; 95009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 96009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 97009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell @Override 98009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell @SuppressWarnings("unchecked") 99009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public T acquire() { 100009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell if (mPoolSize > 0) { 101009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell final int lastPooledIndex = mPoolSize - 1; 102009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell T instance = (T) mPool[lastPooledIndex]; 103009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell mPool[lastPooledIndex] = null; 104009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell mPoolSize--; 105009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell return instance; 106009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 107009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell return null; 108009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 109009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 110009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell @Override 111009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public boolean release(T instance) { 112009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell if (isInPool(instance)) { 113009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell throw new IllegalStateException("Already in the pool!"); 114009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 115009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell if (mPoolSize < mPool.length) { 116009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell mPool[mPoolSize] = instance; 117009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell mPoolSize++; 118009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell return true; 119009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 120009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell return false; 121009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 122009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 123009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell private boolean isInPool(T instance) { 124009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell for (int i = 0; i < mPoolSize; i++) { 125009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell if (mPool[i] == instance) { 126009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell return true; 127009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 128009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 129009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell return false; 130009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 131009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 132009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 133009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell /** 134009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * Synchronized) pool of objects. 135009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 136009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @param <T> The pooled type. 137009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell */ 138009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public static class SynchronizedPool<T> extends SimplePool<T> { 139009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell private final Object mLock = new Object(); 140009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 141009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell /** 142009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * Creates a new instance. 143009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 144009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @param maxPoolSize The max pool size. 145009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * 146009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell * @throws IllegalArgumentException If the max pool size is less than zero. 147009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell */ 148009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public SynchronizedPool(int maxPoolSize) { 149009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell super(maxPoolSize); 150009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 151009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 152009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell @Override 153009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public T acquire() { 154009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell synchronized (mLock) { 155009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell return super.acquire(); 156009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 157009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 158009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell 159009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell @Override 160009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell public boolean release(T element) { 161009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell synchronized (mLock) { 162009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell return super.release(element); 163009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 164009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 165009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell } 166009b4ef9d97e1cc237477e3284fc305bb1438cc9Adam Powell} 167