Templates were updated by pteague. Also a little change by ed_mann.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / util / HashtableOfIntValues.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.util;
12
13 import net.sourceforge.phpdt.core.compiler.CharOperation;
14
15 /**
16  * Hashtable of {char[] --> int}
17  */
18 public final class HashtableOfIntValues implements Cloneable {
19
20         public static final int NO_VALUE = Integer.MIN_VALUE;
21
22         // to avoid using Enumerations, walk the individual tables skipping nulls
23         public char[] keyTable[];
24
25         public int valueTable[];
26
27         public int elementSize; // number of elements in the table
28
29         int threshold;
30
31         public HashtableOfIntValues() {
32                 this(13);
33         }
34
35         public HashtableOfIntValues(int size) {
36
37                 this.elementSize = 0;
38                 this.threshold = size; // size represents the expected number of
39                                                                 // elements
40                 int extraRoom = (int) (size * 1.75f);
41                 if (this.threshold == extraRoom)
42                         extraRoom++;
43                 this.keyTable = new char[extraRoom][];
44                 this.valueTable = new int[extraRoom];
45         }
46
47         public Object clone() throws CloneNotSupportedException {
48                 HashtableOfIntValues result = (HashtableOfIntValues) super.clone();
49                 result.elementSize = this.elementSize;
50                 result.threshold = this.threshold;
51
52                 int length = this.keyTable.length;
53                 result.keyTable = new char[length][];
54                 System.arraycopy(this.keyTable, 0, result.keyTable, 0, length);
55
56                 length = this.valueTable.length;
57                 result.valueTable = new int[length];
58                 System.arraycopy(this.valueTable, 0, result.valueTable, 0, length);
59                 return result;
60         }
61
62         public boolean containsKey(char[] key) {
63
64                 int index = CharOperation.hashCode(key) % valueTable.length;
65                 int keyLength = key.length;
66                 char[] currentKey;
67                 while ((currentKey = keyTable[index]) != null) {
68                         if (currentKey.length == keyLength
69                                         && CharOperation.equals(currentKey, key))
70                                 return true;
71                         index = (index + 1) % keyTable.length;
72                 }
73                 return false;
74         }
75
76         public int get(char[] key) {
77
78                 int index = CharOperation.hashCode(key) % valueTable.length;
79                 int keyLength = key.length;
80                 char[] currentKey;
81                 while ((currentKey = keyTable[index]) != null) {
82                         if (currentKey.length == keyLength
83                                         && CharOperation.equals(currentKey, key))
84                                 return valueTable[index];
85                         index = (index + 1) % keyTable.length;
86                 }
87                 return NO_VALUE;
88         }
89
90         public int put(char[] key, int value) {
91
92                 int index = CharOperation.hashCode(key) % valueTable.length;
93                 int keyLength = key.length;
94                 char[] currentKey;
95                 while ((currentKey = keyTable[index]) != null) {
96                         if (currentKey.length == keyLength
97                                         && CharOperation.equals(currentKey, key))
98                                 return valueTable[index] = value;
99                         index = (index + 1) % keyTable.length;
100                 }
101                 keyTable[index] = key;
102                 valueTable[index] = value;
103
104                 // assumes the threshold is never equal to the size of the table
105                 if (++elementSize > threshold)
106                         rehash();
107                 return value;
108         }
109
110         public int removeKey(char[] key) {
111
112                 int index = CharOperation.hashCode(key) % valueTable.length;
113                 int keyLength = key.length;
114                 char[] currentKey;
115                 while ((currentKey = keyTable[index]) != null) {
116                         if (currentKey.length == keyLength
117                                         && CharOperation.equals(currentKey, key)) {
118                                 int value = valueTable[index];
119                                 elementSize--;
120                                 keyTable[index] = null;
121                                 valueTable[index] = NO_VALUE;
122                                 rehash();
123                                 return value;
124                         }
125                         index = (index + 1) % keyTable.length;
126                 }
127                 return NO_VALUE;
128         }
129
130         private void rehash() {
131
132                 HashtableOfIntValues newHashtable = new HashtableOfIntValues(
133                                 elementSize * 2); // double the number of expected elements
134                 char[] currentKey;
135                 for (int i = keyTable.length; --i >= 0;)
136                         if ((currentKey = keyTable[i]) != null)
137                                 newHashtable.put(currentKey, valueTable[i]);
138
139                 this.keyTable = newHashtable.keyTable;
140                 this.valueTable = newHashtable.valueTable;
141                 this.threshold = newHashtable.threshold;
142         }
143
144         public int size() {
145                 return elementSize;
146         }
147
148         public String toString() {
149                 String s = ""; //$NON-NLS-1$
150                 char[] key;
151                 for (int i = 0, length = valueTable.length; i < length; i++)
152                         if ((key = keyTable[i]) != null)
153                                 s += new String(key) + " -> " + valueTable[i] + "\n"; //$NON-NLS-2$ //$NON-NLS-1$
154                 return s;
155         }
156 }