• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 package com.android.quickstep.util;
17 
18 import android.util.Log;
19 
20 import com.android.systemui.shared.recents.model.Task.TaskKey;
21 
22 import java.util.LinkedHashMap;
23 import java.util.function.Predicate;
24 
25 /**
26  * A simple LRU cache for task key entries
27  * @param <V> The type of the value
28  */
29 public class TaskKeyLruCache<V> {
30 
31     private final MyLinkedHashMap<V> mMap;
32 
TaskKeyLruCache(int maxSize)33     public TaskKeyLruCache(int maxSize) {
34         mMap = new MyLinkedHashMap<>(maxSize);
35     }
36 
37     /**
38      * Removes all entries from the cache
39      */
evictAll()40     public synchronized void evictAll() {
41         mMap.clear();
42     }
43 
44     /**
45      * Removes a particular entry from the cache
46      */
remove(TaskKey key)47     public synchronized void remove(TaskKey key) {
48         mMap.remove(key.id);
49     }
50 
51     /**
52      * Removes all entries matching keyCheck
53      */
removeAll(Predicate<TaskKey> keyCheck)54     public synchronized void removeAll(Predicate<TaskKey> keyCheck) {
55         mMap.entrySet().removeIf(e -> keyCheck.test(e.getValue().mKey));
56     }
57 
58     /**
59      * Gets the entry if it is still valid
60      */
getAndInvalidateIfModified(TaskKey key)61     public synchronized V getAndInvalidateIfModified(TaskKey key) {
62         Entry<V> entry = mMap.get(key.id);
63 
64         if (entry != null && entry.mKey.windowingMode == key.windowingMode
65                 && entry.mKey.lastActiveTime == key.lastActiveTime) {
66             return entry.mValue;
67         } else {
68             remove(key);
69             return null;
70         }
71     }
72 
73     /**
74      * Adds an entry to the cache, optionally evicting the last accessed entry
75      */
put(TaskKey key, V value)76     public final synchronized void put(TaskKey key, V value) {
77         if (key != null && value != null) {
78             mMap.put(key.id, new Entry<>(key, value));
79         } else {
80             Log.e("TaskKeyCache", "Unexpected null key or value: " + key + ", " + value);
81         }
82     }
83 
84     /**
85      * Updates the cache entry if it is already present in the cache
86      */
updateIfAlreadyInCache(int taskId, V data)87     public synchronized void updateIfAlreadyInCache(int taskId, V data) {
88         Entry<V> entry = mMap.get(taskId);
89         if (entry != null) {
90             entry.mValue = data;
91         }
92     }
93 
94     private static class Entry<V> {
95 
96         final TaskKey mKey;
97         V mValue;
98 
Entry(TaskKey key, V value)99         Entry(TaskKey key, V value) {
100             mKey = key;
101             mValue = value;
102         }
103 
104         @Override
hashCode()105         public int hashCode() {
106             return mKey.id;
107         }
108     }
109 
110     private static class MyLinkedHashMap<V> extends LinkedHashMap<Integer, Entry<V>> {
111 
112         private final int mMaxSize;
113 
MyLinkedHashMap(int maxSize)114         MyLinkedHashMap(int maxSize) {
115             super(0, 0.75f, true /* accessOrder */);
116             mMaxSize = maxSize;
117         }
118 
119         @Override
removeEldestEntry(Entry<Integer, TaskKeyLruCache.Entry<V>> eldest)120         protected boolean removeEldestEntry(Entry<Integer, TaskKeyLruCache.Entry<V>> eldest) {
121             return size() > mMaxSize;
122         }
123     }
124 }
125