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