xref: /aosp_15_r20/external/leakcanary2/shark-graph/src/main/java/shark/internal/LruCache.kt (revision d9e8da70d8c9df9a41d7848ae506fb3115cae6e6)
1 package shark.internal
2 
3 import java.util.LinkedHashMap
4 import kotlin.collections.MutableMap.MutableEntry
5 
6 /**
7  * API is a simplified version of android.util.LruCache
8  * Implementation is inspired from http://chriswu.me/blog/a-lru-cache-in-10-lines-of-java/
9  */
10 internal class LruCache<K, V>(
11   val maxSize: Int
12 ) {
13   private val cache: LinkedHashMap<K, V>
14 
15   val size
16     get() = cache.size
17 
18   var putCount: Int = 0
19     private set
20   var evictionCount: Int = 0
21     private set
22   var hitCount: Int = 0
23     private set
24   var missCount: Int = 0
25     private set
26 
27   init {
<lambda>null28     require(maxSize > 0) {
29       "maxSize=$maxSize <= 0"
30     }
31     this.cache = object : LinkedHashMap<K, V>(maxSize, 0.75f, true) {
removeEldestEntrynull32       override fun removeEldestEntry(eldest: MutableEntry<K, V>?) = if (size > maxSize) {
33         evictionCount++
34         true
35       } else {
36         false
37       }
38     }
39   }
40 
getnull41   operator fun get(key: K?): V? {
42     // get() moves the key to the front
43     val value: V? = cache[key]
44     return if (value != null) {
45       hitCount++
46       value
47     } else {
48       missCount++
49       null
50     }
51   }
52 
putnull53   fun put(
54     key: K,
55     value: V
56   ): V? {
57     putCount++
58     return cache.put(key, value)
59   }
60 
removenull61   fun remove(key: K): V? {
62     return cache.remove(key)
63   }
64 
evictAllnull65   fun evictAll() {
66     cache.clear()
67   }
68 
toStringnull69   override fun toString(): String {
70     val accesses = hitCount + missCount
71     val hitPercent = if (accesses != 0) 100 * hitCount / accesses else 0
72     return String.format(
73       "LruCache[maxSize=%d,hits=%d,misses=%d,hitRate=%d%%]",
74       maxSize, hitCount, missCount, hitPercent
75     )
76   }
77 }