1 /*
2  * Copyright (C) 2008 Esmertec AG.
3  * Copyright (C) 2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.google.android.mms.util;
19 
20 import android.compat.annotation.UnsupportedAppUsage;
21 import android.os.Build;
22 import android.util.Log;
23 
24 import java.util.HashMap;
25 
26 public abstract class AbstractCache<K, V> {
27     private static final String TAG = "AbstractCache";
28     private static final boolean DEBUG = false;
29     private static final boolean LOCAL_LOGV = false;
30 
31     private static final int MAX_CACHED_ITEMS  = 500;
32 
33     private final HashMap<K, CacheEntry<V>> mCacheMap;
34 
35     @UnsupportedAppUsage
AbstractCache()36     protected AbstractCache() {
37         mCacheMap = new HashMap<K, CacheEntry<V>>();
38     }
39 
40     @UnsupportedAppUsage
put(K key, V value)41     public boolean put(K key, V value) {
42         if (LOCAL_LOGV) {
43             Log.v(TAG, "Trying to put " + key + " into cache.");
44         }
45 
46         if (mCacheMap.size() >= MAX_CACHED_ITEMS) {
47             // TODO Should remove the oldest or least hit cached entry
48             // and then cache the new one.
49             if (LOCAL_LOGV) {
50                 Log.v(TAG, "Failed! size limitation reached.");
51             }
52             return false;
53         }
54 
55         if (key != null) {
56             CacheEntry<V> cacheEntry = new CacheEntry<V>();
57             cacheEntry.value = value;
58             mCacheMap.put(key, cacheEntry);
59 
60             if (LOCAL_LOGV) {
61                 Log.v(TAG, key + " cached, " + mCacheMap.size() + " items total.");
62             }
63             return true;
64         }
65         return false;
66     }
67 
68     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
get(K key)69     public V get(K key) {
70         if (LOCAL_LOGV) {
71             Log.v(TAG, "Trying to get " + key + " from cache.");
72         }
73 
74         if (key != null) {
75             CacheEntry<V> cacheEntry = mCacheMap.get(key);
76             if (cacheEntry != null) {
77                 cacheEntry.hit++;
78                 if (LOCAL_LOGV) {
79                     Log.v(TAG, key + " hit " + cacheEntry.hit + " times.");
80                 }
81                 return cacheEntry.value;
82             }
83         }
84         return null;
85     }
86 
87     @UnsupportedAppUsage
purge(K key)88     public V purge(K key) {
89         if (LOCAL_LOGV) {
90             Log.v(TAG, "Trying to purge " + key);
91         }
92 
93         CacheEntry<V> v = mCacheMap.remove(key);
94 
95         if (LOCAL_LOGV) {
96             Log.v(TAG, mCacheMap.size() + " items cached.");
97         }
98 
99         return v != null ? v.value : null;
100     }
101 
102     @UnsupportedAppUsage
purgeAll()103     public void purgeAll() {
104         if (LOCAL_LOGV) {
105             Log.v(TAG, "Purging cache, " + mCacheMap.size()
106                     + " items dropped.");
107         }
108         mCacheMap.clear();
109     }
110 
size()111     public int size() {
112         return mCacheMap.size();
113     }
114 
115     private static class CacheEntry<V> {
116         int hit;
117         V value;
118     }
119 }
120