1 /* 2 * Copyright (C) 2015 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 package com.android.camera.processing.memory; 18 19 import com.google.common.base.Preconditions; 20 21 import javax.annotation.Nullable; 22 import javax.annotation.concurrent.GuardedBy; 23 import javax.annotation.concurrent.ThreadSafe; 24 25 /** 26 * Simple resource based memory pool that can automatically return 27 * items back to the memory pool when closed. 28 */ 29 @ThreadSafe 30 public abstract class SimpleLruResourcePool<TKey, TValue> implements LruResourcePool<TKey, TValue> { 31 @GuardedBy("mLock") 32 private final LruPool<TKey, TValue> mLruPool; 33 34 private final Object mLock; 35 SimpleLruResourcePool(int lruSize)36 public SimpleLruResourcePool(int lruSize) { 37 Preconditions.checkArgument(lruSize > 0); 38 39 mLock = new Object(); 40 mLruPool = new LruPool<>(lruSize); 41 } 42 43 @Override acquire(TKey key)44 public Resource<TValue> acquire(TKey key) { 45 TValue value; 46 synchronized (mLock) { 47 value = mLruPool.acquire(key); 48 } 49 50 // We may not reach a point where we have have a value to reuse, 51 // create a new one. 52 if(value == null) { 53 value = create(key); 54 } 55 56 return new SynchronizedResource<>(this, key, value); 57 } 58 59 /** 60 * Create a new value for a given key. 61 */ create(TKey key)62 protected abstract TValue create(TKey key); 63 64 /** 65 * Recycle or reset a given value before it is added back to the pool, 66 * by default, this does nothing. 67 */ recycle(TKey key, TValue value)68 protected TValue recycle(TKey key, TValue value) { 69 return value; 70 } 71 72 /** 73 * Returns an item to the LruPool. 74 */ release(TKey key, TValue value)75 private void release(TKey key, TValue value) { 76 mLruPool.add(key, recycle(key, value)); 77 } 78 79 /** 80 * This is a closable resource that returns the underlying value to the pool 81 * when the object is closed. 82 */ 83 @ThreadSafe 84 private static final class SynchronizedResource<TKey, TValue> implements Resource<TValue> { 85 private final Object mLock; 86 private final SimpleLruResourcePool<TKey, TValue> mPool; 87 88 @GuardedBy("mLock") 89 private TKey mKey; 90 91 @GuardedBy("mLock") 92 private TValue mValue; 93 SynchronizedResource(SimpleLruResourcePool<TKey, TValue> pool, TKey key, TValue value)94 public SynchronizedResource(SimpleLruResourcePool<TKey, TValue> pool, 95 TKey key, TValue value) { 96 mPool = pool; 97 mKey = key; 98 mValue = value; 99 100 mLock = new Object(); 101 } 102 103 @Nullable 104 @Override get()105 public TValue get() { 106 synchronized (mLock) { 107 if (mValue != null) { 108 return mValue; 109 } 110 } 111 return null; 112 } 113 114 @Override close()115 public void close() { 116 synchronized (mLock) { 117 if (mValue != null) { 118 mPool.release(mKey, mValue); 119 mValue = null; 120 mKey = null; 121 } 122 } 123 } 124 } 125 } 126