/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.engine.internal.resolver; import com.google.dart.engine.element.ExecutableElement; /** * This class is used to replace uses of {@code HashMap<String, ExecutableElement>} which are not as * performant as this class. */ public class MemberMap { /** * The current size of this map. */ private int size = 0; /** * The array of keys. */ private String[] keys; /** * The array of ExecutableElement values. */ private ExecutableElement[] values; /** * Default constructor. */ public MemberMap() { this(10); } /** * This constructor takes an initial capacity of the map. * * @param initialCapacity the initial capacity */ public MemberMap(int initialCapacity) { initArrays(initialCapacity); } /** * Copy constructor. */ public MemberMap(MemberMap memberMap) { initArrays(memberMap.size + 5); for (int i = 0; i < memberMap.size; i++) { keys[i] = memberMap.keys[i]; values[i] = memberMap.values[i]; } size = memberMap.size; } /** * Given some key, return the ExecutableElement value from the map, if the key does not exist in * the map, {@code null} is returned. * * @param key some key to look up in the map * @return the associated ExecutableElement value from the map, if the key does not exist in the * map, {@code null} is returned */ public ExecutableElement get(String key) { for (int i = 0; i < size; i++) { if (keys[i] != null && keys[i].equals(key)) { return values[i]; } } return null; } /** * Get and return the key at the specified location. If the key/value pair has been removed from * the set, then {@code null} is returned. * * @param i some non-zero value less than size * @return the key at the passed index * @throw ArrayIndexOutOfBoundsException this exception is thrown if the passed index is less than * zero or greater than or equal to the capacity of the arrays */ public String getKey(int i) { return keys[i]; } /** * The size of the map. * * @return the size of the map. */ public int getSize() { return size; } /** * Get and return the ExecutableElement at the specified location. If the key/value pair has been * removed from the set, then then {@code null} is returned. * * @param i some non-zero value less than size * @return the key at the passed index * @throw ArrayIndexOutOfBoundsException this exception is thrown if the passed index is less than * zero or greater than or equal to the capacity of the arrays */ public ExecutableElement getValue(int i) { return values[i]; } /** * Given some key/value pair, store the pair in the map. If the key exists already, then the new * value overrides the old value. * * @param key the key to store in the map * @param value the ExecutableElement value to store in the map */ public void put(String key, ExecutableElement value) { // If we already have a value with this key, override the value for (int i = 0; i < size; i++) { if (keys[i] != null && keys[i].equals(key)) { values[i] = value; return; } } // If needed, double the size of our arrays and copy values over in both arrays if (size == keys.length) { int newArrayLength = size * 2; String[] keys_new_array = new String[newArrayLength]; ExecutableElement[] values_new_array = new ExecutableElement[newArrayLength]; for (int i = 0; i < size; i++) { keys_new_array[i] = keys[i]; } for (int i = 0; i < size; i++) { values_new_array[i] = values[i]; } keys = keys_new_array; values = values_new_array; } // Put new value at end of array keys[size] = key; values[size] = value; size++; } /** * Given some {@link String} key, this method replaces the associated key and value pair with * {@code null}. The size is not decremented with this call, instead it is expected that the users * check for {@code null}. * * @param key the key of the key/value pair to remove from the map */ public void remove(String key) { for (int i = 0; i < size; i++) { if (keys[i].equals(key)) { keys[i] = null; values[i] = null; return; } } } /** * Sets the ExecutableElement at the specified location. * * @param i some non-zero value less than size * @param value the ExecutableElement value to store in the map */ public void setValue(int i, ExecutableElement value) { values[i] = value; } /** * Initializes {@link #keys} and {@link #values}. */ private void initArrays(int initialCapacity) { keys = new String[initialCapacity]; values = new ExecutableElement[initialCapacity]; } }