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