/** * Returns a hashcode value for the specified symbol. The value * returned by this method must be identical to the value returned * by the <code>hash(char[],int,int)</code> method when called * with the character array that comprises the symbol string. * * @param symbol The symbol to hash. */ public int hash(String symbol) { return fSymbolTable.hash(symbol); } // hash(String):int
/** * Returns a hashcode value for the specified symbol information. * The value returned by this method must be identical to the value * returned by the <code>hash(String)</code> method when called * with the string object created from the symbol information. * * @param buffer The character buffer containing the symbol. * @param offset The offset into the character buffer of the start * of the symbol. * @param length The length of the symbol. */ public int hash(char[] buffer, int offset, int length) { return fSymbolTable.hash(buffer, offset, length); } // hash(char[],int,int):int
private void rehashCommon(final int newCapacity) { int oldCapacity = fBuckets.length; Entry[] oldTable = fBuckets; Entry[] newTable = new Entry[newCapacity]; fThreshold = (int)(newCapacity * fLoadFactor); fBuckets = newTable; fTableSize = fBuckets.length; for (int i = oldCapacity ; i-- > 0 ;) { for (Entry old = oldTable[i] ; old != null ; ) { Entry e = old; old = old.next; int index = hash(e.symbol) % newCapacity; e.next = newTable[index]; newTable[index] = e; } } }
/** * Returns true if the symbol table already contains the specified * symbol. * * @param buffer The buffer containing the symbol to look for. * @param offset The offset into the buffer. * @param length The length of the symbol in the buffer. */ public boolean containsSymbol(char[] buffer, int offset, int length) { // search for identical symbol int bucket = hash(buffer, offset, length) % fTableSize; OUTER: for (Entry entry = fBuckets[bucket]; entry != null; entry = entry.next) { if (length == entry.characters.length) { for (int i = 0; i < length; i++) { if (buffer[offset + i] != entry.characters[i]) { continue OUTER; } } return true; } } return false; } // containsSymbol(char[],int,int):boolean
/** * Returns true if the symbol table already contains the specified * symbol. * * @param symbol The symbol to look for. */ public boolean containsSymbol(String symbol) { // search for identical symbol int bucket = hash(symbol) % fTableSize; int length = symbol.length(); OUTER: for (Entry entry = fBuckets[bucket]; entry != null; entry = entry.next) { if (length == entry.characters.length) { for (int i = 0; i < length; i++) { if (symbol.charAt(i) != entry.characters[i]) { continue OUTER; } } return true; } } return false; } // containsSymbol(String):boolean
/** * Adds the specified symbol to the symbol table and returns a * reference to the unique symbol. If the symbol already exists, * the previous symbol reference is returned instead, in order * guarantee that symbol references remain unique. * * @param symbol The new symbol. */ public String addSymbol(String symbol) { // search for identical symbol int collisionCount = 0; int bucket = hash(symbol) % fTableSize; for (Entry entry = fBuckets[bucket]; entry != null; entry = entry.next) { if (entry.symbol.equals(symbol)) { return entry.symbol; } ++collisionCount; } return addSymbol0(symbol, bucket, collisionCount); } // addSymbol(String):String
private String addSymbol0(char[] buffer, int offset, int length, int bucket, int collisionCount) { if (fCount >= fThreshold) { // Rehash the table if the threshold is exceeded rehash(); bucket = hash(buffer, offset, length) % fTableSize; } else if (collisionCount >= fCollisionThreshold) { // Select a new hash function and rehash the table if // the collision threshold is exceeded. rebalance(); bucket = hash(buffer, offset, length) % fTableSize; } // add new entry Entry entry = new Entry(buffer, offset, length, fBuckets[bucket]); fBuckets[bucket] = entry; ++fCount; return entry.symbol; } // addSymbol0(char[],int,int,int,int):String
int bucket = hash(buffer, offset, length) % fTableSize; OUTER: for (Entry entry = fBuckets[bucket]; entry != null; entry = entry.next) { if (length == entry.characters.length) {
private String addSymbol0(String symbol, int bucket, int collisionCount) { if (fCount >= fThreshold) { // Rehash the table if the threshold is exceeded rehash(); bucket = hash(symbol) % fTableSize; } else if (collisionCount >= fCollisionThreshold) { // Select a new hash function and rehash the table if // the collision threshold is exceeded. rebalance(); bucket = hash(symbol) % fTableSize; } // create new entry Entry entry = new Entry(symbol, fBuckets[bucket]); fBuckets[bucket] = entry; ++fCount; return entry.symbol; } // addSymbol0(String,int,int):String