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 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 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 }