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: import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
014:
015: public final class HashtableOfType {
016: // to avoid using Enumerations, walk the individual tables skipping nulls
017: public char[] keyTable[];
018: public ReferenceBinding valueTable[];
019:
020: public int elementSize; // number of elements in the table
021: int threshold;
022:
023: public HashtableOfType() {
024: this (3);
025: }
026:
027: public HashtableOfType(int size) {
028: this .elementSize = 0;
029: this .threshold = size; // size represents the expected number of elements
030: int extraRoom = (int) (size * 1.75f);
031: if (this .threshold == extraRoom)
032: extraRoom++;
033: this .keyTable = new char[extraRoom][];
034: this .valueTable = new ReferenceBinding[extraRoom];
035: }
036:
037: public boolean containsKey(char[] key) {
038: int length = keyTable.length, index = CharOperation
039: .hashCode(key)
040: % length;
041: int keyLength = key.length;
042: char[] currentKey;
043: while ((currentKey = keyTable[index]) != null) {
044: if (currentKey.length == keyLength
045: && CharOperation.equals(currentKey, key))
046: return true;
047: if (++index == length) {
048: index = 0;
049: }
050: }
051: return false;
052: }
053:
054: public ReferenceBinding get(char[] key) {
055: int length = keyTable.length, index = CharOperation
056: .hashCode(key)
057: % length;
058: int keyLength = key.length;
059: char[] currentKey;
060: while ((currentKey = keyTable[index]) != null) {
061: if (currentKey.length == keyLength
062: && CharOperation.equals(currentKey, key))
063: return valueTable[index];
064: if (++index == length) {
065: index = 0;
066: }
067: }
068: return null;
069: }
070:
071: public ReferenceBinding put(char[] key, ReferenceBinding value) {
072: int length = keyTable.length, index = CharOperation
073: .hashCode(key)
074: % length;
075: int keyLength = key.length;
076: char[] currentKey;
077: while ((currentKey = keyTable[index]) != null) {
078: if (currentKey.length == keyLength
079: && CharOperation.equals(currentKey, key))
080: return valueTable[index] = value;
081: if (++index == length) {
082: index = 0;
083: }
084: }
085: keyTable[index] = key;
086: valueTable[index] = value;
087:
088: // assumes the threshold is never equal to the size of the table
089: if (++elementSize > threshold)
090: rehash();
091: return value;
092: }
093:
094: private void rehash() {
095: HashtableOfType newHashtable = new HashtableOfType(
096: elementSize < 100 ? 100 : elementSize * 2); // double the number of expected elements
097: char[] currentKey;
098: for (int i = keyTable.length; --i >= 0;)
099: if ((currentKey = keyTable[i]) != null)
100: newHashtable.put(currentKey, valueTable[i]);
101:
102: this .keyTable = newHashtable.keyTable;
103: this .valueTable = newHashtable.valueTable;
104: this .threshold = newHashtable.threshold;
105: }
106:
107: public int size() {
108: return elementSize;
109: }
110:
111: public String toString() {
112: String s = ""; //$NON-NLS-1$
113: ReferenceBinding type;
114: for (int i = 0, length = valueTable.length; i < length; i++)
115: if ((type = valueTable[i]) != null)
116: s += type.toString() + "\n"; //$NON-NLS-1$
117: return s;
118: }
119: }
|