Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4cdb0adc authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Simplification of the poolable management utils."

parents 68d1b63e abae2a1b
Loading
Loading
Loading
Loading
+0 −94
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.util;

/**
 * @hide
 */
class FinitePool<T extends Poolable<T>> implements Pool<T> {
    private static final String LOG_TAG = "FinitePool";

    /**
     * Factory used to create new pool objects
     */
    private final PoolableManager<T> mManager;
    /**
     * Maximum number of objects in the pool
     */
    private final int mLimit;
    /**
     * If true, mLimit is ignored
     */
    private final boolean mInfinite;

    /**
     * Next object to acquire
     */
    private T mRoot;
    /**
     * Number of objects in the pool
     */
    private int mPoolCount;

    FinitePool(PoolableManager<T> manager) {
        mManager = manager;
        mLimit = 0;
        mInfinite = true;
    }

    FinitePool(PoolableManager<T> manager, int limit) {
        if (limit <= 0) throw new IllegalArgumentException("The pool limit must be > 0");

        mManager = manager;
        mLimit = limit;
        mInfinite = false;
    }

    public T acquire() {
        T element;

        if (mRoot != null) {
            element = mRoot;
            mRoot = element.getNextPoolable();
            mPoolCount--;
        } else {
            element = mManager.newInstance();
        }

        if (element != null) {
            element.setNextPoolable(null);
            element.setPooled(false);
            mManager.onAcquired(element);            
        }

        return element;
    }

    public void release(T element) {
        if (!element.isPooled()) {
            if (mInfinite || mPoolCount < mLimit) {
                mPoolCount++;
                element.setNextPoolable(mRoot);
                element.setPooled(true);
                mRoot = element;
            }
            mManager.onReleased(element);
        } else {
            Log.w(LOG_TAG, "Element is already in pool: " + element);
        }
    }
}

core/java/android/util/Pool.java

deleted100644 → 0
+0 −25
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.util;

/**
 * @hide
 */
public interface Pool<T extends Poolable<T>> {
    public abstract T acquire();
    public abstract void release(T element);
}
+0 −27
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.util;

/**
 * @hide
 */
public interface Poolable<T> {
    void setNextPoolable(T element);
    T getNextPoolable();
    boolean isPooled();
    void setPooled(boolean isPooled);
}
+0 −27
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.util;

/**
 * @hide
 */
public interface PoolableManager<T extends Poolable<T>> {
    T newInstance();

    void onAcquired(T element);
    void onReleased(T element);
}
+164 −11
Original line number Diff line number Diff line
@@ -17,25 +17,178 @@
package android.util;

/**
 * Helper class for crating pools of objects. An example use looks like this:
 * <pre>
 * public class MyPooledClass {
 *
 *     private static final Pool<MyPooledClass> sPool =
 *             new SynchronizedPool<MyPooledClass>(Pools.POOL_SIZE_INFINITE);
 *
 *     public static MyPooledClass obtain() {
 *         MyPooledClass instance = sPool.acquire();
 *         return (instance != null) ? instance : new MyPooledClass();
 *     }
 *
 *     public void recycle() {
 *          // Clear state if needed.
 *          sPool.release(this);
 *     }
 *
 *     . . .
 * }
 * </pre>
 *
 * @hide
 */
public class Pools {
public final class Pools {

    /**
     * Pool with an infinite size.
     */
    public static final int POOL_SIZE_INFINITE = -1;

    /**
     * Interface for managing a pool of objects.
     *
     * @param <T> The pooled type.
     */
    public static interface Pool<T> {

        /**
         * @return An instance from the pool if such, null otherwise.
         */
        public T acquire();

        /**
         * Release an instance to the pool.
         *
         * @param instance The instance to release.
         * @return Whether the instance was put in the pool.
         *
         * @throws IllegalStateException If the instance is already in the pool.
         */
        public boolean release(T instance);
    }

    private Pools() {
        /* do nothing - hiding constructor */
    }

    public static <T extends Poolable<T>> Pool<T> simplePool(PoolableManager<T> manager) {
        return new FinitePool<T>(manager);
    private static class PoolableHolder<T> {
        T mPoolable;
        PoolableHolder<T> mNext;
    }

    public static <T extends Poolable<T>> Pool<T> finitePool(PoolableManager<T> manager, int limit) {
        return new FinitePool<T>(manager, limit);
    /**
     * Simple (non-synchronized) pool of objects.
     *
     * @param <T> The pooled type.
     */
    public static class SimplePool<T> implements Pool<T> {
        private final int mMaxPoolSize;

        private int mPoolSize;

        private PoolableHolder<T> mEmptyHolders;
        private PoolableHolder<T> mPool;

        /**
         * Creates a new instance.
         *
         * @param maxPoolSize The max pool size.
         *
         * @throws IllegalArgumentException If the max pool size is less than zero.
         *
         * @see Pools#POOL_SIZE_INFINITE
         */
        public SimplePool(int maxPoolSize) {
            if (maxPoolSize <= 0 && maxPoolSize != POOL_SIZE_INFINITE) {
                throw new IllegalArgumentException("The max pool size must be > 0");
            }
            mMaxPoolSize = maxPoolSize;
        }

        @Override
        public T acquire() {
            if (mPool != null) {
                PoolableHolder<T> holder = mPool;
                mPool = holder.mNext;
                T poolable = holder.mPoolable;
                holder.mPoolable = null;
                holder.mNext = mEmptyHolders;
                mEmptyHolders = holder;
                mPoolSize--;
                return poolable;
            }
            return null;
        }

        @Override
        public boolean release(T instance) {
            if (isInPool(instance)) {
                throw new IllegalStateException("Already in the pool!");
            }
            if (mMaxPoolSize == POOL_SIZE_INFINITE || mPoolSize < mMaxPoolSize) {
                PoolableHolder<T> holder = mEmptyHolders;
                if (holder == null) {
                    holder = new PoolableHolder<T>();
                } else {
                    mEmptyHolders = holder.mNext;
                }
                holder.mPoolable = instance;
                holder.mNext = mPool;
                mPool = holder;
                mPoolSize++;
                return true;
            }
            return false;
        }

        private boolean isInPool(T instance) {
            PoolableHolder<T> current = mPool;
            while (current != null) {
                if (current.mPoolable == instance) {
                    return true;
                }
                current = current.mNext;
            }
            return false;
        }
    }

    /**
     * Synchronized) pool of objects.
     *
     * @param <T> The pooled type.
     */
    public static class SynchronizedPool<T> extends SimplePool<T> {
        private final Object mLock = new Object();

    public static <T extends Poolable<T>> Pool<T> synchronizedPool(Pool<T> pool) {
        return new SynchronizedPool<T>(pool);
        /**
         * Creates a new instance.
         *
         * @param maxPoolSize The max pool size.
         *
         * @throws IllegalArgumentException If the max pool size is less than zero.
         *
         * @see Pools#POOL_SIZE_INFINITE
         */
        public SynchronizedPool(int maxPoolSize) {
            super(maxPoolSize);
        }

    public static <T extends Poolable<T>> Pool<T> synchronizedPool(Pool<T> pool, Object lock) {
        return new SynchronizedPool<T>(pool, lock);
        @Override
        public T acquire() {
            synchronized (mLock) {
                return super.acquire();
            }
        }

        @Override
        public boolean release(T element) {
            synchronized (mLock) {
                return super.release(element);
            }
        }
    }
}
Loading