1 11 package org.eclipse.core.internal.registry; 12 13 import java.io.*; 14 15 18 public final class HashtableOfStringAndInt implements Cloneable { 19 public static final int MISSING_ELEMENT = Integer.MIN_VALUE; 20 21 private String keyTable[]; 23 private int valueTable[]; 24 25 private int elementSize; private int threshold; 27 private static final float GROWTH_FACTOR = 1.33f; 28 29 public HashtableOfStringAndInt() { 30 this(13); 31 } 32 33 public HashtableOfStringAndInt(int size) { 34 this.elementSize = 0; 35 this.threshold = size; int extraRoom = (int) (size * 1.75f); 37 if (this.threshold == extraRoom) 38 extraRoom++; 39 this.keyTable = new String [extraRoom]; 40 this.valueTable = new int[extraRoom]; 41 } 42 43 public Object clone() throws CloneNotSupportedException { 44 throw new CloneNotSupportedException (); 45 } 58 59 public boolean containsKey(String key) { 60 int index = (key.hashCode() & 0x7FFFFFFF) % valueTable.length; 61 int keyLength = key.length(); 62 String currentKey; 63 while ((currentKey = keyTable[index]) != null) { 64 if (currentKey.length() == keyLength && currentKey.equals(key)) 65 return true; 66 index = (index + 1) % keyTable.length; 67 } 68 return false; 69 } 70 71 public int get(String key) { 72 int index = (key.hashCode() & 0x7FFFFFFF) % valueTable.length; 73 int keyLength = key.length(); 74 String currentKey; 75 while ((currentKey = keyTable[index]) != null) { 76 if (currentKey.length() == keyLength && currentKey.equals(key)) 77 return valueTable[index]; 78 index = (index + 1) % keyTable.length; 79 } 80 return MISSING_ELEMENT; 81 } 82 83 public int put(String key, int value) { 84 int index = (key.hashCode() & 0x7FFFFFFF) % valueTable.length; 85 int keyLength = key.length(); 86 String currentKey; 87 while ((currentKey = keyTable[index]) != null) { 88 if (currentKey.length() == keyLength && currentKey.equals(key)) 89 return valueTable[index] = value; 90 index = (index + 1) % keyTable.length; 91 } 92 keyTable[index] = key; 93 valueTable[index] = value; 94 95 if (++elementSize > threshold) 97 rehash(); 98 return value; 99 } 100 101 public int removeKey(String key) { 102 int index = (key.hashCode() & 0x7FFFFFFF) % valueTable.length; 103 int keyLength = key.length(); 104 String currentKey; 105 while ((currentKey = keyTable[index]) != null) { 106 if (currentKey.length() == keyLength && currentKey.equals(key)) { 107 int value = valueTable[index]; 108 elementSize--; 109 keyTable[index] = null; 110 valueTable[index] = MISSING_ELEMENT; 111 rehash(); 112 return value; 113 } 114 index = (index + 1) % keyTable.length; 115 } 116 return MISSING_ELEMENT; 117 } 118 119 private void rehash() { 120 HashtableOfStringAndInt newHashtable = new HashtableOfStringAndInt((int) (elementSize * GROWTH_FACTOR)); 121 String currentKey; 122 for (int i = keyTable.length; --i >= 0;) 123 if ((currentKey = keyTable[i]) != null) 124 newHashtable.put(currentKey, valueTable[i]); 125 126 this.keyTable = newHashtable.keyTable; 127 this.valueTable = newHashtable.valueTable; 128 this.threshold = newHashtable.threshold; 129 } 130 131 public int size() { 132 return elementSize; 133 } 134 135 public String toString() { 136 String s = ""; int object; 138 for (int i = 0, length = valueTable.length; i < length; i++) 139 if ((object = valueTable[i]) != MISSING_ELEMENT) 140 s += new String (keyTable[i]) + " -> " + object + "\n"; return s; 142 } 143 144 public int[] getValues() { 145 int keyTableLength = keyTable.length; 146 int[] result = new int[size()]; 147 int j = 0; 148 for (int i = 0; i < keyTableLength; i++) { 149 if (keyTable[i] != null) 150 result[j++] = valueTable[i]; 151 } 152 return result; 153 } 154 155 public void save(DataOutputStream out) throws IOException { 156 out.writeInt(elementSize); 157 int tableSize = keyTable.length; 158 out.writeInt(tableSize); 159 out.writeInt(threshold); 160 for (int i = 0; i < tableSize; i++) { 161 writeStringOrNull(keyTable[i], out); 162 out.writeInt(valueTable[i]); 163 } 164 } 165 166 169 public void save(DataOutputStream out, RegistryObjectManager objectManager) throws IOException { 170 HashtableOfStringAndInt filteredHashtable = new HashtableOfStringAndInt((int) (elementSize * GROWTH_FACTOR)); 171 String currentKey; 172 for (int i = keyTable.length; --i >= 0;) 173 if ((currentKey = keyTable[i]) != null && objectManager.shouldPersist(valueTable[i])) 174 filteredHashtable.put(currentKey, valueTable[i]); 175 filteredHashtable.save(out); 176 } 177 178 public void load(DataInputStream in) throws IOException { 179 elementSize = in.readInt(); 180 int tableSize = in.readInt(); 181 threshold = in.readInt(); 182 boolean fastMode = true; 183 if (((double) tableSize / elementSize) < GROWTH_FACTOR) { 184 keyTable = new String [(int) (elementSize * GROWTH_FACTOR)]; 185 valueTable = new int[(int) (elementSize * GROWTH_FACTOR)]; 186 elementSize = 0; 187 fastMode = false; 188 } else { 189 keyTable = new String [tableSize]; 190 valueTable = new int[tableSize]; 191 } 192 for (int i = 0; i < tableSize; i++) { 193 String key = readStringOrNull(in); 194 int value = in.readInt(); 195 if (fastMode) { 196 keyTable[i] = key; 197 valueTable[i] = value; 198 } else { 199 if (key != null) 200 put(key, value); 201 } 202 } 203 } 204 205 private static final byte NULL = 0; 206 private static final byte OBJECT = 1; 207 208 private void writeStringOrNull(String string, DataOutputStream out) throws IOException { 209 if (string == null) 210 out.writeByte(NULL); 211 else { 212 out.writeByte(OBJECT); 213 out.writeUTF(string); 214 } 215 } 216 217 private String readStringOrNull(DataInputStream in) throws IOException { 218 byte type = in.readByte(); 219 if (type == NULL) 220 return null; 221 return in.readUTF(); 222 } 223 224 } 225 | Popular Tags |