KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > codegen > CharArrayCache


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.compiler.codegen;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14
15 public class CharArrayCache {
16     // to avoid using Enumerations, walk the individual tables skipping nulls
17
public char[] keyTable[];
18     public int valueTable[];
19     int elementSize; // number of elements in the table
20
int threshold;
21 /**
22  * Constructs a new, empty hashtable. A default capacity is used.
23  * Note that the hashtable will automatically grow when it gets full.
24  */

25 public CharArrayCache() {
26     this(9);
27 }
28 /**
29  * Constructs a new, empty hashtable with the specified initial
30  * capacity.
31  * @param initialCapacity int
32  * the initial number of buckets; must be less than Integer.MAX_VALUE / 2
33  */

34 public CharArrayCache(int initialCapacity) {
35     this.elementSize = 0;
36     this.threshold = (initialCapacity * 2) / 3; // faster than float operation
37
this.keyTable = new char[initialCapacity][];
38     this.valueTable = new int[initialCapacity];
39 }
40 /**
41  * Clears the hash table so that it has no more elements in it.
42  */

43 public void clear() {
44     for (int i = this.keyTable.length; --i >= 0;) {
45         this.keyTable[i] = null;
46         this.valueTable[i] = 0;
47     }
48     this.elementSize = 0;
49 }
50 /** Returns true if the collection contains an element for the key.
51  *
52  * @param key char[] the key that we are looking for
53  * @return boolean
54  */

55 public boolean containsKey(char[] key) {
56     int index = hashCodeChar(key), length = this.keyTable.length;
57     while (this.keyTable[index] != null) {
58         if (CharOperation.equals(this.keyTable[index], key))
59             return true;
60         if (++index == length) { // faster than modulo
61
index = 0;
62         }
63     }
64     return false;
65 }
66 /** Gets the object associated with the specified key in the
67  * hashtable.
68  * @param key <CODE>char[]</CODE> the specified key
69  * @return int the element for the key or -1 if the key is not
70  * defined in the hash table.
71  */

72 public int get(char[] key) {
73     int index = hashCodeChar(key), length = this.keyTable.length;
74     while (this.keyTable[index] != null) {
75         if (CharOperation.equals(this.keyTable[index], key))
76             return this.valueTable[index];
77         if (++index == length) { // faster than modulo
78
index = 0;
79         }
80     }
81     return -1;
82 }
83 private int hashCodeChar(char[] val) {
84     final int length = val.length;
85     int hash = 0;
86     final int n = 3; // number of characters skipped
87
for (int i = 0; i < length; i += n) {
88         hash += val[i];
89     }
90     return (hash & 0x7FFFFFFF) % this.keyTable.length;
91 }
92 /**
93  * Puts the specified element into the hashtable if it wasn't there already,
94  * using the specified key. The element may be retrieved by doing a get() with the same key.
95  * The key and the element cannot be null.
96  *
97  * @param key the given key in the hashtable
98  * @param value the given value
99  * @return int the old value of the key, or -value if it did not have one.
100  */

101 public int putIfAbsent(char[] key, int value) {
102     int index = hashCodeChar(key), length = this.keyTable.length;
103     while (this.keyTable[index] != null) {
104         if (CharOperation.equals(this.keyTable[index], key))
105             return this.valueTable[index];
106         if (++index == length) { // faster than modulo
107
index = 0;
108         }
109     }
110     this.keyTable[index] = key;
111     this.valueTable[index] = value;
112
113     // assumes the threshold is never equal to the size of the table
114
if (++this.elementSize > this.threshold)
115         rehash();
116     return -value; // negative when added (value is assumed to be > 0)
117
}
118
119 /**
120  * Puts the specified element into the hashtable, using the specified
121  * key. The element may be retrieved by doing a get() with the same key.
122  * The key and the element cannot be null.
123  *
124  * @param key <CODE>Object</CODE> the specified key in the hashtable
125  * @param value <CODE>int</CODE> the specified element
126  * @return int the old value of the key, or -1 if it did not have one.
127  */

128 private int put(char[] key, int value) {
129     int index = hashCodeChar(key), length = this.keyTable.length;
130     while (this.keyTable[index] != null) {
131         if (CharOperation.equals(this.keyTable[index], key))
132             return this.valueTable[index] = value;
133         if (++index == length) { // faster than modulo
134
index = 0;
135         }
136     }
137     this.keyTable[index] = key;
138     this.valueTable[index] = value;
139
140     // assumes the threshold is never equal to the size of the table
141
if (++this.elementSize > this.threshold)
142         rehash();
143     return value;
144 }
145 /**
146  * Rehashes the content of the table into a bigger table.
147  * This method is called automatically when the hashtable's
148  * size exceeds the threshold.
149  */

150 private void rehash() {
151     CharArrayCache newHashtable = new CharArrayCache(this.keyTable.length * 2);
152     for (int i = this.keyTable.length; --i >= 0;)
153         if (this.keyTable[i] != null)
154             newHashtable.put(this.keyTable[i], this.valueTable[i]);
155
156     this.keyTable = newHashtable.keyTable;
157     this.valueTable = newHashtable.valueTable;
158     this.threshold = newHashtable.threshold;
159 }
160 /** Remove the object associated with the specified key in the
161  * hashtable.
162  * @param key <CODE>char[]</CODE> the specified key
163  */

164 public void remove(char[] key) {
165     int index = hashCodeChar(key), length = this.keyTable.length;
166     while (this.keyTable[index] != null) {
167         if (CharOperation.equals(this.keyTable[index], key)) {
168             this.valueTable[index] = 0;
169             this.keyTable[index] = null;
170             return;
171         }
172         if (++index == length) { // faster than modulo
173
index = 0;
174         }
175     }
176 }
177 /**
178  * Returns the key corresponding to the value. Returns null if the
179  * receiver doesn't contain the value.
180  * @param value int the value that we are looking for
181  * @return Object
182  */

183 public char[] returnKeyFor(int value) {
184     for (int i = this.keyTable.length; i-- > 0;) {
185         if (this.valueTable[i] == value) {
186             return this.keyTable[i];
187         }
188     }
189     return null;
190 }
191 /**
192  * Returns the number of elements contained in the hashtable.
193  *
194  * @return <CODE>int</CODE> The size of the table
195  */

196 public int size() {
197     return this.elementSize;
198 }
199 /**
200  * Converts to a rather lengthy String.
201  *
202  * return String the ascii representation of the receiver
203  */

204 public String JavaDoc toString() {
205     int max = size();
206     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
207     buf.append("{"); //$NON-NLS-1$
208
for (int i = 0; i < max; ++i) {
209         if (this.keyTable[i] != null) {
210             buf.append(this.keyTable[i]).append("->").append(this.valueTable[i]); //$NON-NLS-1$
211
}
212         if (i < max) {
213             buf.append(", "); //$NON-NLS-1$
214
}
215     }
216     buf.append("}"); //$NON-NLS-1$
217
return buf.toString();
218 }
219 }
220
Popular Tags