140 lines
3.7 KiB
Java
140 lines
3.7 KiB
Java
package org.apache.xerces.util;
|
|
|
|
public class SymbolTable {
|
|
protected static final int TABLE_SIZE = 101;
|
|
|
|
protected Entry[] fBuckets = null;
|
|
|
|
protected int fTableSize;
|
|
|
|
public SymbolTable() {
|
|
this(101);
|
|
}
|
|
|
|
public SymbolTable(int tableSize) {
|
|
this.fTableSize = tableSize;
|
|
this.fBuckets = new Entry[this.fTableSize];
|
|
}
|
|
|
|
public String addSymbol(String symbol) {
|
|
int bucket = hash(symbol) % this.fTableSize;
|
|
int length = symbol.length();
|
|
Entry entry;
|
|
for (entry = this.fBuckets[bucket]; entry != null; entry = entry.next) {
|
|
if (length == entry.characters.length) {
|
|
int i = 0;
|
|
while (true) {
|
|
if (i < length) {
|
|
if (symbol.charAt(i) != entry.characters[i])
|
|
break;
|
|
i++;
|
|
continue;
|
|
}
|
|
return entry.symbol;
|
|
}
|
|
}
|
|
}
|
|
entry = new Entry(symbol, this.fBuckets[bucket]);
|
|
this.fBuckets[bucket] = entry;
|
|
return entry.symbol;
|
|
}
|
|
|
|
public String addSymbol(char[] buffer, int offset, int length) {
|
|
int bucket = hash(buffer, offset, length) % this.fTableSize;
|
|
Entry entry;
|
|
for (entry = this.fBuckets[bucket]; entry != null; entry = entry.next) {
|
|
if (length == entry.characters.length) {
|
|
int i = 0;
|
|
while (true) {
|
|
if (i < length) {
|
|
if (buffer[offset + i] != entry.characters[i])
|
|
break;
|
|
i++;
|
|
continue;
|
|
}
|
|
return entry.symbol;
|
|
}
|
|
}
|
|
}
|
|
entry = new Entry(buffer, offset, length, this.fBuckets[bucket]);
|
|
this.fBuckets[bucket] = entry;
|
|
return entry.symbol;
|
|
}
|
|
|
|
public int hash(String symbol) {
|
|
int code = 0;
|
|
int length = symbol.length();
|
|
for (int i = 0; i < length; i++)
|
|
code = code * 37 + symbol.charAt(i);
|
|
return code & 0x7FFFFFF;
|
|
}
|
|
|
|
public int hash(char[] buffer, int offset, int length) {
|
|
int code = 0;
|
|
for (int i = 0; i < length; i++)
|
|
code = code * 37 + buffer[offset + i];
|
|
return code & 0x7FFFFFF;
|
|
}
|
|
|
|
public boolean containsSymbol(String symbol) {
|
|
int bucket = hash(symbol) % this.fTableSize;
|
|
int length = symbol.length();
|
|
for (Entry entry = this.fBuckets[bucket]; entry != null; entry = entry.next) {
|
|
if (length == entry.characters.length) {
|
|
int i = 0;
|
|
while (true) {
|
|
if (i < length) {
|
|
if (symbol.charAt(i) != entry.characters[i])
|
|
break;
|
|
i++;
|
|
continue;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean containsSymbol(char[] buffer, int offset, int length) {
|
|
int bucket = hash(buffer, offset, length) % this.fTableSize;
|
|
for (Entry entry = this.fBuckets[bucket]; entry != null; entry = entry.next) {
|
|
if (length == entry.characters.length) {
|
|
int i = 0;
|
|
while (true) {
|
|
if (i < length) {
|
|
if (buffer[offset + i] != entry.characters[i])
|
|
break;
|
|
i++;
|
|
continue;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected static final class Entry {
|
|
public String symbol;
|
|
|
|
public char[] characters;
|
|
|
|
public Entry next;
|
|
|
|
public Entry(String symbol, Entry next) {
|
|
this.symbol = symbol.intern();
|
|
this.characters = new char[symbol.length()];
|
|
symbol.getChars(0, this.characters.length, this.characters, 0);
|
|
this.next = next;
|
|
}
|
|
|
|
public Entry(char[] ch, int offset, int length, Entry next) {
|
|
this.characters = new char[length];
|
|
System.arraycopy(ch, offset, this.characters, 0, length);
|
|
this.symbol = (new String(this.characters)).intern();
|
|
this.next = next;
|
|
}
|
|
}
|
|
}
|