blob: 70581be80dce89553ebae10abaa55358596dbd86 [file] [log] [blame]
Romain Guyd1b3dd02009-03-31 17:53:57 -07001/*
2 * Copyright (C) 2009 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
17package android.util;
18
19/**
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080020 * Helper class for crating pools of objects. An example use looks like this:
21 * <pre>
22 * public class MyPooledClass {
23 *
Svetoslav Ganovbe922dc2012-11-30 16:46:26 -080024 * private static final SynchronizedPool<MyPooledClass> sPool =
25 * new SynchronizedPool<MyPooledClass>(10);
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080026 *
27 * public static MyPooledClass obtain() {
28 * MyPooledClass instance = sPool.acquire();
29 * return (instance != null) ? instance : new MyPooledClass();
30 * }
31 *
32 * public void recycle() {
33 * // Clear state if needed.
34 * sPool.release(this);
35 * }
36 *
37 * . . .
38 * }
39 * </pre>
40 *
Romain Guyd1b3dd02009-03-31 17:53:57 -070041 * @hide
42 */
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080043public final class Pools {
44
45 /**
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080046 * Interface for managing a pool of objects.
47 *
48 * @param <T> The pooled type.
49 */
50 public static interface Pool<T> {
51
52 /**
53 * @return An instance from the pool if such, null otherwise.
54 */
55 public T acquire();
56
57 /**
58 * Release an instance to the pool.
59 *
60 * @param instance The instance to release.
61 * @return Whether the instance was put in the pool.
62 *
63 * @throws IllegalStateException If the instance is already in the pool.
64 */
65 public boolean release(T instance);
66 }
67
Romain Guy10b40432009-04-02 09:03:39 -070068 private Pools() {
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080069 /* do nothing - hiding constructor */
Romain Guyd1b3dd02009-03-31 17:53:57 -070070 }
71
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080072 /**
73 * Simple (non-synchronized) pool of objects.
74 *
75 * @param <T> The pooled type.
76 */
77 public static class SimplePool<T> implements Pool<T> {
Svetoslav Ganov60fba772012-12-13 16:01:00 -080078 private final Object[] mPool;
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080079
80 private int mPoolSize;
81
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080082 /**
83 * Creates a new instance.
84 *
85 * @param maxPoolSize The max pool size.
86 *
87 * @throws IllegalArgumentException If the max pool size is less than zero.
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080088 */
89 public SimplePool(int maxPoolSize) {
Svetoslav Ganovbe922dc2012-11-30 16:46:26 -080090 if (maxPoolSize <= 0) {
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080091 throw new IllegalArgumentException("The max pool size must be > 0");
92 }
Svetoslav Ganov60fba772012-12-13 16:01:00 -080093 mPool = new Object[maxPoolSize];
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080094 }
95
96 @Override
Svetoslav Ganov60fba772012-12-13 16:01:00 -080097 @SuppressWarnings("unchecked")
Svetoslav Ganovabae2a12012-11-27 16:59:37 -080098 public T acquire() {
Svetoslav Ganov60fba772012-12-13 16:01:00 -080099 if (mPoolSize > 0) {
100 final int lastPooledIndex = mPoolSize - 1;
101 T instance = (T) mPool[lastPooledIndex];
102 mPool[lastPooledIndex] = null;
Svetoslav Ganovabae2a12012-11-27 16:59:37 -0800103 mPoolSize--;
Svetoslav Ganov60fba772012-12-13 16:01:00 -0800104 return instance;
Svetoslav Ganovabae2a12012-11-27 16:59:37 -0800105 }
106 return null;
107 }
108
109 @Override
110 public boolean release(T instance) {
111 if (isInPool(instance)) {
112 throw new IllegalStateException("Already in the pool!");
113 }
Svetoslav Ganov60fba772012-12-13 16:01:00 -0800114 if (mPoolSize < mPool.length) {
115 mPool[mPoolSize] = instance;
Svetoslav Ganovabae2a12012-11-27 16:59:37 -0800116 mPoolSize++;
117 return true;
118 }
119 return false;
120 }
121
122 private boolean isInPool(T instance) {
Svetoslav Ganov60fba772012-12-13 16:01:00 -0800123 for (int i = 0; i < mPoolSize; i++) {
124 if (mPool[i] == instance) {
Svetoslav Ganovabae2a12012-11-27 16:59:37 -0800125 return true;
126 }
Svetoslav Ganovabae2a12012-11-27 16:59:37 -0800127 }
128 return false;
129 }
Romain Guyd1b3dd02009-03-31 17:53:57 -0700130 }
131
Svetoslav Ganovabae2a12012-11-27 16:59:37 -0800132 /**
133 * Synchronized) pool of objects.
134 *
135 * @param <T> The pooled type.
136 */
137 public static class SynchronizedPool<T> extends SimplePool<T> {
138 private final Object mLock = new Object();
139
140 /**
141 * Creates a new instance.
142 *
143 * @param maxPoolSize The max pool size.
144 *
145 * @throws IllegalArgumentException If the max pool size is less than zero.
Svetoslav Ganovabae2a12012-11-27 16:59:37 -0800146 */
147 public SynchronizedPool(int maxPoolSize) {
148 super(maxPoolSize);
149 }
150
151 @Override
152 public T acquire() {
153 synchronized (mLock) {
154 return super.acquire();
155 }
156 }
157
158 @Override
159 public boolean release(T element) {
160 synchronized (mLock) {
161 return super.release(element);
162 }
163 }
Romain Guyd1b3dd02009-03-31 17:53:57 -0700164 }
165}