1 /* 2 * Copyright (c) 2017, 2017, 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 package jdk.internal.vm.compiler.collections; 26 27 import java.util.Iterator; 28 import java.util.Map; 29 import java.util.function.BiFunction; 30 31 /** 32 * Memory efficient map data structure. 33 * 34 * @since 1.0 35 */ 36 public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> { 37 38 /** 39 * Associates {@code value} with {@code key} in this map. If the map previously contained a 40 * mapping for {@code key}, the old value is replaced by {@code value}. 41 * 42 * @return the previous value associated with {@code key}, or {@code null} if there was no 43 * mapping for {@code key}. 44 * @since 1.0 45 */ 46 V put(K key, V value); 47 48 /** 49 * Copies all of the mappings from {@code other} to this map. 50 * 51 * @since 1.0 52 */ 53 default void putAll(EconomicMap<K, V> other) { 54 MapCursor<K, V> e = other.getEntries(); 55 while (e.advance()) { 56 put(e.getKey(), e.getValue()); 57 } 58 } 59 60 /** 61 * Copies all of the mappings from {@code other} to this map. 62 * 63 * @since 1.0 64 */ 65 default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) { 66 UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries(); 67 while (entry.advance()) { 68 put(entry.getKey(), entry.getValue()); 69 } 70 } 71 72 /** 73 * Removes all of the mappings from this map. The map will be empty after this call returns. 74 * 75 * @since 1.0 76 */ 77 void clear(); 78 79 /** 80 * Removes the mapping for {@code key} from this map if it is present. The map will not contain 81 * a mapping for {@code key} once the call returns. 82 * 83 * @return the previous value associated with {@code key}, or {@code null} if there was no 84 * mapping for {@code key}. 85 * @since 1.0 86 */ 87 V removeKey(K key); 88 89 /** 90 * Returns a {@link MapCursor} view of the mappings contained in this map. 91 * 92 * @since 1.0 93 */ 94 @Override 95 MapCursor<K, V> getEntries(); 96 97 /** 98 * Replaces each entry's value with the result of invoking {@code function} on that entry until 99 * all entries have been processed or the function throws an exception. Exceptions thrown by the 100 * function are relayed to the caller. 101 * 102 * @since 1.0 103 */ 104 void replaceAll(BiFunction<? super K, ? super V, ? extends V> function); 105 106 /** 107 * Creates a new map that guarantees insertion order on the key set with the default 108 * {@link Equivalence#DEFAULT} comparison strategy for keys. 109 * 110 * @since 1.0 111 */ 112 static <K, V> EconomicMap<K, V> create() { 113 return EconomicMap.create(Equivalence.DEFAULT); 114 } 115 116 /** 117 * Creates a new map that guarantees insertion order on the key set with the default 118 * {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified 119 * capacity. 120 * 121 * @since 1.0 122 */ 123 static <K, V> EconomicMap<K, V> create(int initialCapacity) { 124 return EconomicMap.create(Equivalence.DEFAULT, initialCapacity); 125 } 126 127 /** 128 * Creates a new map that guarantees insertion order on the key set with the given comparison 129 * strategy for keys. 130 * 131 * @since 1.0 132 */ 133 static <K, V> EconomicMap<K, V> create(Equivalence strategy) { 134 return EconomicMapImpl.create(strategy, false); 135 } 136 137 /** 138 * Creates a new map that guarantees insertion order on the key set with the default 139 * {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the 140 * specified existing map. 141 * 142 * @since 1.0 143 */ 144 static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> m) { 145 return EconomicMap.create(Equivalence.DEFAULT, m); 146 } 147 148 /** 149 * Creates a new map that guarantees insertion order on the key set and copies all elements from 150 * the specified existing map. 151 * 152 * @since 1.0 153 */ 154 static <K, V> EconomicMap<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> m) { 155 return EconomicMapImpl.create(strategy, m, false); 156 } 157 158 /** 159 * Creates a new map that guarantees insertion order on the key set and initializes with a 160 * specified capacity. 161 * 162 * @since 1.0 163 */ 164 static <K, V> EconomicMap<K, V> create(Equivalence strategy, int initialCapacity) { 165 return EconomicMapImpl.create(strategy, initialCapacity, false); 166 } 167 168 /** 169 * Wraps an existing {@link Map} as an {@link EconomicMap}. 170 * 171 * @since 1.0 172 */ 173 static <K, V> EconomicMap<K, V> wrapMap(Map<K, V> map) { 174 return new EconomicMap<K, V>() { 175 176 @Override 177 public V get(K key) { 178 V result = map.get(key); 179 return result; 180 } 181 182 @Override 183 public V put(K key, V value) { 184 V result = map.put(key, value); 185 return result; 186 } 187 188 @Override 189 public int size() { 190 int result = map.size(); 191 return result; 192 } 193 194 @Override 195 public boolean containsKey(K key) { 196 return map.containsKey(key); 197 } 198 199 @Override 200 public void clear() { 201 map.clear(); 202 } 203 204 @Override 205 public V removeKey(K key) { 206 V result = map.remove(key); 207 return result; 208 } 209 210 @Override 211 public Iterable<V> getValues() { 212 return map.values(); 213 } 214 215 @Override 216 public Iterable<K> getKeys() { 217 return map.keySet(); 218 } 219 220 @Override 221 public boolean isEmpty() { 222 return map.isEmpty(); 223 } 224 225 @Override 226 public MapCursor<K, V> getEntries() { 227 Iterator<java.util.Map.Entry<K, V>> iterator = map.entrySet().iterator(); 228 return new MapCursor<K, V>() { 229 230 private Map.Entry<K, V> current; 231 232 @Override 233 public boolean advance() { 234 boolean result = iterator.hasNext(); 235 if (result) { 236 current = iterator.next(); 237 } 238 239 return result; 240 } 241 242 @Override 243 public K getKey() { 244 return current.getKey(); 245 } 246 247 @Override 248 public V getValue() { 249 return current.getValue(); 250 } 251 252 @Override 253 public void remove() { 254 iterator.remove(); 255 } 256 }; 257 } 258 259 @Override 260 public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { 261 map.replaceAll(function); 262 } 263 }; 264 } 265 }