first scanner /parser copied from the jdt java version
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / codegen / CharArrayCache.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v0.5 
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v05.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.codegen;
12
13 import net.sourceforge.phpdt.internal.compiler.util.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(13);
27 }
28 /**
29  * Constructs a new, empty hashtable with the specified initial
30  * capacity.
31  * @param initialCapacity int
32  *      the initial number of buckets
33  */
34 public CharArrayCache(int initialCapacity) {
35         this.elementSize = 0;
36         this.threshold = (int) (initialCapacity * 0.66f);
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 = keyTable.length; --i >= 0;) {
45                 keyTable[i] = null;
46                 valueTable[i] = 0;
47         }
48         elementSize = 0;
49 }
50 /** Returns true if the collection contains an element for the key.
51  *
52  * @param char[] key the key that we are looking for
53  * @return boolean
54  */
55 public boolean containsKey(char[] key) {
56         int index = hashCodeChar(key);
57         while (keyTable[index] != null) {
58                 if (CharOperation.equals(keyTable[index], key))
59                         return true;
60                 index = (index + 1) % keyTable.length;
61         }
62         return false;
63 }
64 /** Gets the object associated with the specified key in the
65  * hashtable.
66  * @param key <CODE>char[]</CODE> the specified key
67  * @return int the element for the key or -1 if the key is not
68  *      defined in the hash table.
69  */
70 public int get(char[] key) {
71         int index = hashCodeChar(key);
72         while (keyTable[index] != null) {
73                 if (CharOperation.equals(keyTable[index], key))
74                         return valueTable[index];
75                 index = (index + 1) % keyTable.length;
76         }
77         return -1;
78 }
79 private int hashCodeChar(char[] val) {
80         int length = val.length;
81         int hash = 0;
82         int n = 2; // number of characters skipped
83         for (int i = 0; i < length; i += n) {
84                 hash += val[i];
85         }
86         return (hash & 0x7FFFFFFF) % keyTable.length;
87 }
88 /**
89  * Puts the specified element into the hashtable, using the specified
90  * key.  The element may be retrieved by doing a get() with the same key.
91  * The key and the element cannot be null. 
92  * 
93  * @param key <CODE>Object</CODE> the specified key in the hashtable
94  * @param value <CODE>int</CODE> the specified element
95  * @return int the old value of the key, or -1 if it did not have one.
96  */
97 public int put(char[] key, int value) { 
98         int index = hashCodeChar(key);
99         while (keyTable[index] != null) {
100                 if (CharOperation.equals(keyTable[index], key))
101                         return valueTable[index] = value;
102                 index = (index + 1) % keyTable.length;
103         }
104         keyTable[index] = key;
105         valueTable[index] = value;
106
107         // assumes the threshold is never equal to the size of the table
108         if (++elementSize > threshold)
109                 rehash();
110         return value;
111 }
112 /**
113  * Rehashes the content of the table into a bigger table.
114  * This method is called automatically when the hashtable's
115  * size exceeds the threshold.
116  */
117 private void rehash() {
118         CharArrayCache newHashtable = new CharArrayCache(keyTable.length * 2);
119         for (int i = keyTable.length; --i >= 0;)
120                 if (keyTable[i] != null)
121                         newHashtable.put(keyTable[i], valueTable[i]);
122
123         this.keyTable = newHashtable.keyTable;
124         this.valueTable = newHashtable.valueTable;
125         this.threshold = newHashtable.threshold;
126 }
127 /** Remove the object associated with the specified key in the
128  * hashtable.
129  * @param key <CODE>char[]</CODE> the specified key
130  */
131 public void remove(char[] key) {
132         int index = hashCodeChar(key);
133         while (keyTable[index] != null) {
134                 if (CharOperation.equals(keyTable[index], key)) {
135                         valueTable[index] = 0;
136                         keyTable[index] = null;
137                         return;
138                 }
139                 index = (index + 1) % keyTable.length;
140         }
141 }
142 /**
143  * Returns the key corresponding to the value. Returns null if the
144  * receiver doesn't contain the value.
145  * @param value int the value that we are looking for
146  * @return Object
147  */
148 public char[] returnKeyFor(int value) {
149         for (int i = keyTable.length; i-- > 0;) {
150                 if (valueTable[i] == value) {
151                         return keyTable[i];
152                 }
153         }
154         return null;
155 }
156 /**
157  * Returns the number of elements contained in the hashtable.
158  *
159  * @return <CODE>int</CODE> The size of the table
160  */
161 public int size() {
162         return elementSize;
163 }
164 /**
165  * Converts to a rather lengthy String.
166  *
167  * return String the ascii representation of the receiver
168  */
169 public String toString() {
170         int max = size();
171         StringBuffer buf = new StringBuffer();
172         buf.append("{"); //$NON-NLS-1$
173         for (int i = 0; i < max; ++i) {
174                 if (keyTable[i] != null) {
175                         buf.append(keyTable[i]).append("->").append(valueTable[i]); //$NON-NLS-1$
176                 }
177                 if (i < max) {
178                         buf.append(", "); //$NON-NLS-1$
179                 }
180         }
181         buf.append("}"); //$NON-NLS-1$
182         return buf.toString();
183 }
184 }