1 /*
2  * Copyright 2018 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 androidx.arch.core.internal;
18 
19 import androidx.annotation.NonNull;
20 import androidx.annotation.RestrictTo;
21 
22 import java.util.HashMap;
23 import java.util.Map;
24 
25 /**
26  * Poor's man LinkedHashMap, which supports modifications during iterations.
27  * Takes more memory that {@link SafeIterableMap}
28  * It is NOT thread safe.
29  *
30  * @param <K> Key type
31  * @param <V> Value type
32  * @hide
33  */
34 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
35 public class FastSafeIterableMap<K, V> extends SafeIterableMap<K, V> {
36 
37     private HashMap<K, Entry<K, V>> mHashMap = new HashMap<>();
38 
39     @Override
get(K k)40     protected Entry<K, V> get(K k) {
41         return mHashMap.get(k);
42     }
43 
44     @Override
putIfAbsent(@onNull K key, @NonNull V v)45     public V putIfAbsent(@NonNull K key, @NonNull V v) {
46         Entry<K, V> current = get(key);
47         if (current != null) {
48             return current.mValue;
49         }
50         mHashMap.put(key, put(key, v));
51         return null;
52     }
53 
54     @Override
remove(@onNull K key)55     public V remove(@NonNull K key) {
56         V removed = super.remove(key);
57         mHashMap.remove(key);
58         return removed;
59     }
60 
61     /**
62      * Returns {@code true} if this map contains a mapping for the specified
63      * key.
64      */
contains(K key)65     public boolean contains(K key) {
66         return mHashMap.containsKey(key);
67     }
68 
69     /**
70      * Return an entry added to prior to an entry associated with the given key.
71      *
72      * @param k the key
73      */
ceil(K k)74     public Map.Entry<K, V> ceil(K k) {
75         if (contains(k)) {
76             return mHashMap.get(k).mPrevious;
77         }
78         return null;
79     }
80 }
81