001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.compiler.util;
011:
012: import org.eclipse.jdt.core.compiler.CharOperation;
013:
014: /**
015: * Hashtable of {char[] --> int}
016: */
017: public final class HashtableOfIntValues implements Cloneable {
018:
019: public static final int NO_VALUE = Integer.MIN_VALUE;
020:
021: // to avoid using Enumerations, walk the individual tables skipping nulls
022: public char[] keyTable[];
023: public int valueTable[];
024:
025: public int elementSize; // number of elements in the table
026: int threshold;
027:
028: public HashtableOfIntValues() {
029: this (13);
030: }
031:
032: public HashtableOfIntValues(int size) {
033:
034: this .elementSize = 0;
035: this .threshold = size; // size represents the expected number of elements
036: int extraRoom = (int) (size * 1.75f);
037: if (this .threshold == extraRoom)
038: extraRoom++;
039: this .keyTable = new char[extraRoom][];
040: this .valueTable = new int[extraRoom];
041: }
042:
043: public Object clone() throws CloneNotSupportedException {
044: HashtableOfIntValues result = (HashtableOfIntValues) super
045: .clone();
046: result.elementSize = this .elementSize;
047: result.threshold = this .threshold;
048:
049: int length = this .keyTable.length;
050: result.keyTable = new char[length][];
051: System.arraycopy(this .keyTable, 0, result.keyTable, 0, length);
052:
053: length = this .valueTable.length;
054: result.valueTable = new int[length];
055: System.arraycopy(this .valueTable, 0, result.valueTable, 0,
056: length);
057: return result;
058: }
059:
060: public boolean containsKey(char[] key) {
061: int length = keyTable.length, index = CharOperation
062: .hashCode(key)
063: % length;
064: int keyLength = key.length;
065: char[] currentKey;
066: while ((currentKey = keyTable[index]) != null) {
067: if (currentKey.length == keyLength
068: && CharOperation.equals(currentKey, key))
069: return true;
070: if (++index == length) {
071: index = 0;
072: }
073: }
074: return false;
075: }
076:
077: public int get(char[] key) {
078: int length = keyTable.length, index = CharOperation
079: .hashCode(key)
080: % length;
081: int keyLength = key.length;
082: char[] currentKey;
083: while ((currentKey = keyTable[index]) != null) {
084: if (currentKey.length == keyLength
085: && CharOperation.equals(currentKey, key))
086: return valueTable[index];
087: if (++index == length) {
088: index = 0;
089: }
090: }
091: return NO_VALUE;
092: }
093:
094: public int put(char[] key, int value) {
095: int length = keyTable.length, index = CharOperation
096: .hashCode(key)
097: % length;
098: int keyLength = key.length;
099: char[] currentKey;
100: while ((currentKey = keyTable[index]) != null) {
101: if (currentKey.length == keyLength
102: && CharOperation.equals(currentKey, key))
103: return valueTable[index] = value;
104: if (++index == length) {
105: index = 0;
106: }
107: }
108: keyTable[index] = key;
109: valueTable[index] = value;
110:
111: // assumes the threshold is never equal to the size of the table
112: if (++elementSize > threshold)
113: rehash();
114: return value;
115: }
116:
117: public int removeKey(char[] key) {
118: int length = keyTable.length, index = CharOperation
119: .hashCode(key)
120: % length;
121: int keyLength = key.length;
122: char[] currentKey;
123: while ((currentKey = keyTable[index]) != null) {
124: if (currentKey.length == keyLength
125: && CharOperation.equals(currentKey, key)) {
126: int value = valueTable[index];
127: elementSize--;
128: keyTable[index] = null;
129: valueTable[index] = NO_VALUE;
130: rehash();
131: return value;
132: }
133: if (++index == length) {
134: index = 0;
135: }
136: }
137: return NO_VALUE;
138: }
139:
140: private void rehash() {
141:
142: HashtableOfIntValues newHashtable = new HashtableOfIntValues(
143: elementSize * 2); // double the number of expected elements
144: char[] currentKey;
145: for (int i = keyTable.length; --i >= 0;)
146: if ((currentKey = keyTable[i]) != null)
147: newHashtable.put(currentKey, valueTable[i]);
148:
149: this .keyTable = newHashtable.keyTable;
150: this .valueTable = newHashtable.valueTable;
151: this .threshold = newHashtable.threshold;
152: }
153:
154: public int size() {
155: return elementSize;
156: }
157:
158: public String toString() {
159: String s = ""; //$NON-NLS-1$
160: char[] key;
161: for (int i = 0, length = valueTable.length; i < length; i++)
162: if ((key = keyTable[i]) != null)
163: s += new String(key) + " -> " + valueTable[i] + "\n"; //$NON-NLS-2$ //$NON-NLS-1$
164: return s;
165: }
166: }
|