1 /* 2 * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * The Universal Permissive License (UPL), Version 1.0 6 * 7 * Subject to the condition set forth below, permission is hereby granted to any 8 * person obtaining a copy of this software, associated documentation and/or 9 * data (collectively the "Software"), free of charge and under any and all 10 * copyright rights in the Software, and any and all patent rights owned or 11 * freely licensable by each licensor hereunder covering either (i) the 12 * unmodified Software as contributed to or provided by such licensor, or (ii) 13 * the Larger Works (as defined below), to deal in both 14 * 15 * (a) the Software, and 16 * 17 * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 18 * one is included with the Software each a "Larger Work" to which the Software 19 * is contributed by such licensors), 20 * 21 * without restriction, including without limitation the rights to copy, create 22 * derivative works of, display, perform, and distribute the Software and make, 23 * use, sell, offer for sale, import, export, have made, and have sold the 24 * Software and the Larger Work(s), and to sublicense the foregoing rights on 25 * either these or other terms. 26 * 27 * This license is subject to the following condition: 28 * 29 * The above copyright notice and either this complete permission notice or at a 30 * minimum a reference to the UPL must be included in all copies or substantial 31 * portions of the Software. 32 * 33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 36 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 38 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 39 * SOFTWARE. 40 */ 41 package jdk.internal.vm.compiler.collections; 42 43 import java.util.Iterator; 44 import java.util.Map; 45 import java.util.function.BiFunction; 46 47 /** 48 * Memory efficient map data structure. 49 * 50 * @since 1.0 51 */ 52 public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> { 53 54 /** 55 * Associates {@code value} with {@code key} in this map. If the map previously contained a 56 * mapping for {@code key}, the old value is replaced by {@code value}. 57 * 58 * @return the previous value associated with {@code key}, or {@code null} if there was no 59 * mapping for {@code key}. 60 * @since 1.0 61 */ 62 V put(K key, V value); 63 64 /** 65 * Copies all of the mappings from {@code other} to this map. 66 * 67 * @since 1.0 68 */ 69 default void putAll(EconomicMap<K, V> other) { 70 MapCursor<K, V> e = other.getEntries(); 71 while (e.advance()) { 72 put(e.getKey(), e.getValue()); 73 } 74 } 75 76 /** 77 * Copies all of the mappings from {@code other} to this map. 78 * 79 * @since 1.0 80 */ 81 default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) { 82 UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries(); 83 while (entry.advance()) { 84 put(entry.getKey(), entry.getValue()); 85 } 86 } 87 88 /** 89 * Removes all of the mappings from this map. The map will be empty after this call returns. 90 * 91 * @since 1.0 92 */ 93 void clear(); 94 95 /** 96 * Removes the mapping for {@code key} from this map if it is present. The map will not contain 97 * a mapping for {@code key} once the call returns. 98 * 99 * @return the previous value associated with {@code key}, or {@code null} if there was no 100 * mapping for {@code key}. 101 * @since 1.0 102 */ 103 V removeKey(K key); 104 105 /** 106 * Returns a {@link MapCursor} view of the mappings contained in this map. 107 * 108 * @since 1.0 109 */ 110 @Override 111 MapCursor<K, V> getEntries(); 112 113 /** 114 * Replaces each entry's value with the result of invoking {@code function} on that entry until 115 * all entries have been processed or the function throws an exception. Exceptions thrown by the 116 * function are relayed to the caller. 117 * 118 * @since 1.0 119 */ 120 void replaceAll(BiFunction<? super K, ? super V, ? extends V> function); 121 122 /** 123 * Creates a new map that guarantees insertion order on the key set with the default 124 * {@link Equivalence#DEFAULT} comparison strategy for keys. 125 * 126 * @since 1.0 127 */ 128 static <K, V> EconomicMap<K, V> create() { 129 return EconomicMap.create(Equivalence.DEFAULT); 130 } 131 132 /** 133 * Creates a new map that guarantees insertion order on the key set with the default 134 * {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified 135 * capacity. 136 * 137 * @since 1.0 138 */ 139 static <K, V> EconomicMap<K, V> create(int initialCapacity) { 140 return EconomicMap.create(Equivalence.DEFAULT, initialCapacity); 141 } 142 143 /** 144 * Creates a new map that guarantees insertion order on the key set with the given comparison 145 * strategy for keys. 146 * 147 * @since 1.0 148 */ 149 static <K, V> EconomicMap<K, V> create(Equivalence strategy) { 150 return EconomicMapImpl.create(strategy, false); 151 } 152 153 /** 154 * Creates a new map that guarantees insertion order on the key set with the default 155 * {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the 156 * specified existing map. 157 * 158 * @since 1.0 159 */ 160 static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> m) { 161 return EconomicMap.create(Equivalence.DEFAULT, m); 162 } 163 164 /** 165 * Creates a new map that guarantees insertion order on the key set and copies all elements from 166 * the specified existing map. 167 * 168 * @since 1.0 169 */ 170 static <K, V> EconomicMap<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> m) { 171 return EconomicMapImpl.create(strategy, m, false); 172 } 173 174 /** 175 * Creates a new map that guarantees insertion order on the key set and initializes with a 176 * specified capacity. 177 * 178 * @since 1.0 179 */ 180 static <K, V> EconomicMap<K, V> create(Equivalence strategy, int initialCapacity) { 181 return EconomicMapImpl.create(strategy, initialCapacity, false); 182 } 183 184 /** 185 * Wraps an existing {@link Map} as an {@link EconomicMap}. 186 * 187 * @since 1.0 188 */ 189 static <K, V> EconomicMap<K, V> wrapMap(Map<K, V> map) { 190 return new EconomicMap<K, V>() { 191 192 @Override 193 public V get(K key) { 194 V result = map.get(key); 195 return result; 196 } 197 198 @Override 199 public V put(K key, V value) { 200 V result = map.put(key, value); 201 return result; 202 } 203 204 @Override 205 public int size() { 206 int result = map.size(); 207 return result; 208 } 209 210 @Override 211 public boolean containsKey(K key) { 212 return map.containsKey(key); 213 } 214 215 @Override 216 public void clear() { 217 map.clear(); 218 } 219 220 @Override 221 public V removeKey(K key) { 222 V result = map.remove(key); 223 return result; 224 } 225 226 @Override 227 public Iterable<V> getValues() { 228 return map.values(); 229 } 230 231 @Override 232 public Iterable<K> getKeys() { 233 return map.keySet(); 234 } 235 236 @Override 237 public boolean isEmpty() { 238 return map.isEmpty(); 239 } 240 241 @Override 242 public MapCursor<K, V> getEntries() { 243 Iterator<java.util.Map.Entry<K, V>> iterator = map.entrySet().iterator(); 244 return new MapCursor<K, V>() { 245 246 private Map.Entry<K, V> current; 247 248 @Override 249 public boolean advance() { 250 boolean result = iterator.hasNext(); 251 if (result) { 252 current = iterator.next(); 253 } 254 255 return result; 256 } 257 258 @Override 259 public K getKey() { 260 return current.getKey(); 261 } 262 263 @Override 264 public V getValue() { 265 return current.getValue(); 266 } 267 268 @Override 269 public void remove() { 270 iterator.remove(); 271 } 272 }; 273 } 274 275 @Override 276 public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { 277 map.replaceAll(function); 278 } 279 }; 280 } 281 }