/* * Copyright (C) 2015 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 com.android.camera.processing.memory; import com.google.common.base.Preconditions; import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.ThreadSafe; /** * Simple resource based memory pool that can automatically return * items back to the memory pool when closed. */ @ThreadSafe public abstract class SimpleLruResourcePool implements LruResourcePool { @GuardedBy("mLock") private final LruPool mLruPool; private final Object mLock; public SimpleLruResourcePool(int lruSize) { Preconditions.checkArgument(lruSize > 0); mLock = new Object(); mLruPool = new LruPool<>(lruSize); } @Override public Resource acquire(TKey key) { TValue value; synchronized (mLock) { value = mLruPool.acquire(key); } // We may not reach a point where we have have a value to reuse, // create a new one. if(value == null) { value = create(key); } return new SynchronizedResource<>(this, key, value); } /** * Create a new value for a given key. */ protected abstract TValue create(TKey key); /** * Recycle or reset a given value before it is added back to the pool, * by default, this does nothing. */ protected TValue recycle(TKey key, TValue value) { return value; } /** * Returns an item to the LruPool. */ private void release(TKey key, TValue value) { mLruPool.add(key, recycle(key, value)); } /** * This is a closable resource that returns the underlying value to the pool * when the object is closed. */ @ThreadSafe private static final class SynchronizedResource implements Resource { private final Object mLock; private final SimpleLruResourcePool mPool; @GuardedBy("mLock") private TKey mKey; @GuardedBy("mLock") private TValue mValue; public SynchronizedResource(SimpleLruResourcePool pool, TKey key, TValue value) { mPool = pool; mKey = key; mValue = value; mLock = new Object(); } @Nullable @Override public TValue get() { synchronized (mLock) { if (mValue != null) { return mValue; } } return null; } @Override public void close() { synchronized (mLock) { if (mValue != null) { mPool.release(mKey, mValue); mValue = null; mKey = null; } } } } }