1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-31 04:03:27 +02:00

from a patch originally from Dave Daoust, consolidate the Scanner2 data

structures into a heirarchy, and for the char[] maps/sets, if the capacity is
<= 2, then don't use the hash and just do a linear search.

also clean up a couple of uses of ObjectSet that had size 0 in the symbol table,
use EMPTY_SET insteard.
This commit is contained in:
Andrew Niefer 2004-08-11 17:56:20 +00:00
parent 6c18d73efc
commit a7880c8fdc
12 changed files with 185 additions and 915 deletions

View file

@ -81,7 +81,7 @@ public class ObjectMapTest extends TestCase {
ObjectMap map = new ObjectMap( 1 );
assertEquals( map.size(), 0 );
assertEquals( map.capacity(), 1 );
assertEquals( map.capacity(), 2 );
Object [][] res = new Object [][] { { "0", "o0" }, //$NON-NLS-1$//$NON-NLS-2$
{ "1", "o1" }, //$NON-NLS-1$//$NON-NLS-2$
@ -98,7 +98,7 @@ public class ObjectMapTest extends TestCase {
ObjectMap map = new ObjectMap( 1 );
assertEquals( map.size(), 0 );
assertEquals( map.capacity(), 1 );
assertEquals( map.capacity(), 2 );
Object [][] res = new Object [][] { { new HashObject(0), "o0" }, //$NON-NLS-1$
{ new HashObject(1), "o1" }, //$NON-NLS-1$
@ -115,7 +115,7 @@ public class ObjectMapTest extends TestCase {
ObjectMap map = new ObjectMap( 1 );
assertEquals( map.size(), 0 );
assertEquals( map.capacity(), 1 );
assertEquals( map.capacity(), 2 );
Object [][] res = new Object [][] { { "0", "o0" }, //$NON-NLS-1$ //$NON-NLS-2$
{ "1", "o1" } }; //$NON-NLS-1$ //$NON-NLS-2$

View file

@ -666,7 +666,7 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
public IParameterizedSymbol unqualifiedFunctionLookup( char[] name, final List parameters ) throws ParserSymbolTableException{
//figure out the set of associated scopes first, so we can remove those that are searched
//during the normal lookup to avoid doing them twice
final ObjectSet associated = new ObjectSet(0);
ObjectSet associated = ObjectSet.EMPTY_SET;
//collect associated namespaces & classes.
int size = ( parameters == null ) ? 0 : parameters.size();
@ -683,6 +683,8 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
continue;
}
if( associated == ObjectSet.EMPTY_SET )
associated = new ObjectSet( 2 );
ParserSymbolTable.getAssociatedScopes( paramType, associated );
//if T is a pointer to a data member of class X, its associated namespaces and classes
@ -696,13 +698,13 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
}
}
}
final ObjectSet associatedData = associated;
LookupData data = new LookupData( name ){
public ObjectSet getAssociated() { return assoc; }
public List getParameters() { return params; }
public TypeFilter getFilter() { return FUNCTION_FILTER; }
final private ObjectSet assoc = associated;
final private ObjectSet assoc = associatedData;
final private List params = ( parameters == null ) ? Collections.EMPTY_LIST : parameters;
};

View file

@ -244,6 +244,8 @@ public class ParserSymbolTable {
//namespaces are searched at most once
if( !data.visited.containsKey( temp ) ){
if( data.visited == ObjectSet.EMPTY_SET )
data.visited = new ObjectSet( 2 );
data.visited.put( temp );
CharArrayObjectMap map = lookupInContained( data, temp );
@ -658,6 +660,8 @@ public class ParserSymbolTable {
if( !wrapper.isVirtual() || !data.visited.containsKey( parent ) ){
if( wrapper.isVirtual() ){
if( data.visited == ObjectSet.EMPTY_SET )
data.visited = new ObjectSet(2);
data.visited.put( parent );
}
@ -2219,7 +2223,7 @@ public class ParserSymbolTable {
public char[] name;
public ObjectMap usingDirectives;
public ObjectSet visited = new ObjectSet(0); //used to ensure we don't visit things more than once
public ObjectSet visited = ObjectSet.EMPTY_SET; //used to ensure we don't visit things more than once
public ObjectSet inheritanceChain; //used to detect circular inheritance
public ISymbol templateMember; //to assit with template member defs

View file

@ -13,7 +13,7 @@ package org.eclipse.cdt.internal.core.parser.scanner2;
/**
* @author Doug Schaefer
*/
public class CharArrayIntMap extends CharArrayMap {
public class CharArrayIntMap extends CharTable {
private int[] valueTable;
public final int undefined;
@ -28,10 +28,16 @@ public class CharArrayIntMap extends CharArrayMap {
int[] oldValueTable = valueTable;
valueTable = new int[size];
System.arraycopy(oldValueTable, 0, valueTable, 0, oldValueTable.length);
super.resize(size);
}
public void clear() {
super.clear();
for( int i = 0; i < capacity(); i++ )
valueTable[i] = undefined;
}
public int put(char[] key, int start, int length, int value) {
int i = add(key, start, length);
int i = addIndex(key, start, length);
int oldvalue = valueTable[i];
valueTable[i] = value;
return oldvalue;
@ -45,7 +51,6 @@ public class CharArrayIntMap extends CharArrayMap {
int i = lookup(key, start, length);
if (i >= 0)
return valueTable[i];
return -1;
return undefined;
}
}

View file

@ -1,186 +0,0 @@
/**********************************************************************
* Copyright (c) 2004 IBM and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
/**
* @author Doug Schaefer
*/
public abstract class CharArrayMap {
private char[][] keyTable;
private int[] hashTable;
private int[] nextTable;
protected int currEntry = -1;
protected CharArrayMap(int initialSize) {
int size = 1;
while (size < initialSize)
size <<= 1;
keyTable = new char[size][];
hashTable = new int[size * 2];
nextTable = new int[size];
}
protected int capacity() {
return keyTable.length;
}
private int hash(char[] buffer, int start, int len) {
return CharArrayUtils.hash(buffer, start, len) & (hashTable.length - 1);
}
private int hash(char[] buffer) {
return hash(buffer, 0, buffer.length);
}
private void insert(int i) {
insert(i, hash(keyTable[i], 0, keyTable[i].length));
}
private void insert(int i, int hash) {
if (hashTable[hash] == 0) {
hashTable[hash] = i + 1;
} else {
// need to link
int j = hashTable[hash] - 1;
while (nextTable[j] != 0)
j = nextTable[j] - 1;
nextTable[j] = i + 1;
}
}
protected void resize(int size) {
char[][] oldKeyTable = keyTable;
keyTable = new char[size][];
System.arraycopy(oldKeyTable, 0, keyTable, 0, oldKeyTable.length);
// Need to rehash everything
hashTable = new int[size * 2];
nextTable = new int[size];
for (int i = 0; i < oldKeyTable.length; ++i) {
insert(i);
}
}
private void resize() {
resize(keyTable.length << 1);
}
protected final int add(char[] buffer, int start, int len) {
int hash = hash(buffer, start, len);
if (hashTable[hash] == 0) {
if( (currEntry + 1) >= keyTable.length){
//need to recompute hash for this add, recurse.
resize();
return add( buffer, start, len );
}
currEntry++;
keyTable[currEntry] = CharArrayUtils.extract(buffer, start, len);
insert(currEntry, hash);
return currEntry;
}
// is the key already registered?
int i = hashTable[hash] - 1;
if (CharArrayUtils.equals(buffer, start, len, keyTable[i]))
// yup
return i;
// follow the next chain
int last = i;
for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1) {
if (CharArrayUtils.equals(buffer, start, len, keyTable[i]))
// yup this time
return i;
last = i;
}
// nope, add it in
if (currEntry + 1 >= keyTable.length){
//need to recompute hash for this add, recurse
resize();
return add( buffer, start, len );
}
currEntry++;
keyTable[currEntry] = CharArrayUtils.extract(buffer, start, len);
nextTable[last] = currEntry + 1;
return currEntry;
}
protected final int lookup(char[] buffer, int start, int len) {
int hash = hash(buffer, start, len);
if (hashTable[hash] == 0)
return -1;
int i = hashTable[hash] - 1;
if (CharArrayUtils.equals(buffer, start, len, keyTable[i]))
return i;
// Follow the next chain
for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1)
if (CharArrayUtils.equals(buffer, start, len, keyTable[i]))
return i;
return -1;
}
protected void removeEntry(int i) {
// Remove the hash entry
int hash = hash(keyTable[i]);
if (hashTable[hash] == i + 1)
hashTable[hash] = nextTable[i];
else {
// find entry pointing to me
int j = hashTable[hash] - 1;
while (nextTable[j] != 0 && nextTable[j] != i + 1)
j = nextTable[j] - 1;
nextTable[j] = nextTable[i];
}
if (i < currEntry) {
// shift everything over
System.arraycopy(keyTable, i + 1, keyTable, i, currEntry - i);
System.arraycopy(nextTable, i + 1, nextTable, i, currEntry - i);
// adjust hash and next entries for things that moved
for (int j = 0; j < hashTable.length; ++j)
if (hashTable[j] > i)
--hashTable[j];
for (int j = 0; j < nextTable.length; ++j)
if (nextTable[j] > i)
--nextTable[j];
}
// last entry is now free
keyTable[currEntry] = null;
nextTable[currEntry] = 0;
--currEntry;
}
public void dumpNexts() {
for (int i = 0; i < nextTable.length; ++i) {
if (nextTable[i] == 0)
continue;
System.out.print(i);
for (int j = nextTable[i] - 1; j >= 0; j = nextTable[j] - 1)
System.out.print(" -> " + j); //$NON-NLS-1$
System.out.println(""); //$NON-NLS-1$
}
}
}

View file

@ -10,38 +10,30 @@
***********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* @author Doug Schaefer
*/
public class CharArrayObjectMap {//extends CharArrayMap {
public class CharArrayObjectMap extends CharTable {
public static final CharArrayObjectMap EMPTY_MAP = new CharArrayObjectMap( 0 ){
public Object clone() { return this; }
public List toList() { return Collections.EMPTY_LIST; }
public Object put( char[] key, int start, int length, Object value )
{ throw new UnsupportedOperationException(); }
};
private char[][] keyTable;
private int[] hashTable;
private int[] nextTable;
private Object[] valueTable;
private int currEntry = -1;
public CharArrayObjectMap(int initialSize) {
int size = 1;
while (size < initialSize)
size <<= 1;
keyTable = new char[size][];
hashTable = new int[size * 2];
nextTable = new int[size];
valueTable = new Object[size];
super(initialSize);
valueTable = new Object[capacity()];
}
public Object put(char[] key, int start, int length, Object value) {
int i = add(key, start, length);
int i = addIndex(key, start, length);
Object oldvalue = valueTable[i];
valueTable[i] = value;
return oldvalue;
@ -65,21 +57,9 @@ public class CharArrayObjectMap {//extends CharArrayMap {
final public Object getAt( int i ){
if( i < 0 || i > currEntry )
return null;
// char [] key = keyAt( i );
// if( key == null ) return null;
//
// return get( key, 0, key.length );
return valueTable[i];
}
final public char[] keyAt( int i ){
if( i < 0 || i > currEntry )
return null;
return keyTable[ i ];
}
final public Object remove(char[] key, int start, int length) {
int i = lookup(key, start, length);
if (i < 0)
@ -87,232 +67,46 @@ public class CharArrayObjectMap {//extends CharArrayMap {
Object value = valueTable[i];
if (i < currEntry)
System.arraycopy(valueTable, i + 1, valueTable, i, currEntry - i);
valueTable[currEntry] = null;
removeEntry(i);
return value;
}
final public Object remove(char[] key) {
return remove(key, 0, key.length);
}
public Object clone(){
int size = capacity();
CharArrayObjectMap newTable = new CharArrayObjectMap( size );
newTable.keyTable = new char[ size ][];
newTable.hashTable = new int[ size*2 ];
newTable.nextTable = new int[ size ];
newTable.valueTable = new Object[ capacity() ];
System.arraycopy(valueTable, 0, newTable.valueTable, 0, valueTable.length);
System.arraycopy(keyTable, 0, newTable.keyTable, 0, keyTable.length);
System.arraycopy(hashTable, 0, newTable.hashTable, 0, hashTable.length);
System.arraycopy(nextTable, 0, newTable.nextTable, 0, nextTable.length);
if( hashTable != null )
System.arraycopy(hashTable, 0, newTable.hashTable, 0, hashTable.length);
if( nextTable != null )
System.arraycopy(nextTable, 0, newTable.nextTable, 0, nextTable.length);
newTable.currEntry = currEntry;
return newTable;
}
final public int size(){
return currEntry + 1;
}
final public void clear(){
for( int i = 0; i < keyTable.length; i++ ){
keyTable[i] = null;
hashTable[ 2*i ] = 0;
hashTable[ 2*i + 1 ] = 0;
nextTable[i] = 0;
valueTable[i] = null;
}
currEntry = -1;
}
final public int capacity() {
return keyTable.length;
}
final public boolean containsKey( char[] key ){
return lookup( key, 0, key.length ) != -1;
}
final public char [][] keyArray(){
char [][] keys = new char[ size() ][];
System.arraycopy( keyTable, 0, keys, 0, keys.length );
return keys;
}
final public boolean isEmpty(){
return currEntry == -1;
}
final public void sort( Comparator c ) {
if( size() > 1 ){
quickSort( c, 0, size() - 1 );
rehash( size(), false );
}
}
private void resize() {
resize(keyTable.length << 1);
}
private void resize(int size) {
protected void resize(int size) {
Object[] oldValueTable = valueTable;
valueTable = new Object[size];
System.arraycopy(oldValueTable, 0, valueTable, 0, oldValueTable.length);
Object[] oldKeyTable = keyTable;
keyTable = new char[size][];
System.arraycopy(oldKeyTable, 0, keyTable, 0, oldKeyTable.length);
// Need to rehash everything
rehash( oldKeyTable.length, true );
super.resize(size);
}
private int hash(char[] buffer, int start, int len) {
return CharArrayUtils.hash(buffer, start, len) & (hashTable.length - 1);
}
private void insert(int i) {
insert(i, hash(keyTable[i], 0, keyTable[i].length));
}
private void insert(int i, int hash) {
if (hashTable[hash] == 0) {
hashTable[hash] = i + 1;
} else {
// need to link
int j = hashTable[hash] - 1;
while (nextTable[j] != 0)
j = nextTable[j] - 1;
nextTable[j] = i + 1;
}
public void clear() {
super.clear();
for( int i = 0; i < capacity(); i++ )
valueTable[i] = null;
}
private void rehash( int n, boolean reallocate ){
if( reallocate ){
hashTable = new int[ keyTable.length * 2 ];
nextTable = new int[ keyTable.length ];
} else {
for( int i = 0; i < keyTable.length; i++ ){
hashTable[2*i] = 0;
hashTable[2*i+1] = 0;
nextTable[i] = 0;
}
}
for (int i = 0; i < n; ++i) {
insert(i);
}
}
private int add(char[] buffer, int start, int len) {
int hash = hash(buffer, start, len);
if (hashTable[hash] == 0) {
if( (currEntry + 1) >= keyTable.length){
//need to recompute hash for this add, recurse.
resize();
return add( buffer, start, len );
}
currEntry++;
keyTable[currEntry] = CharArrayUtils.extract(buffer, start, len);
insert(currEntry, hash);
return currEntry;
}
// is the key already registered?
int i = hashTable[hash] - 1;
if (CharArrayUtils.equals(buffer, start, len, keyTable[i]))
// yup
return i;
// follow the next chain
int last = i;
for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1) {
if (CharArrayUtils.equals(buffer, start, len, keyTable[i]))
// yup this time
return i;
last = i;
}
// nope, add it in
if (currEntry + 1 >= keyTable.length){
//need to recompute hash for this add, recurse
resize();
return add( buffer, start, len );
}
currEntry++;
keyTable[currEntry] = CharArrayUtils.extract(buffer, start, len);
nextTable[last] = currEntry + 1;
return currEntry;
}
private void removeEntry(int i) {
if (i < currEntry)
System.arraycopy(valueTable, i + 1, valueTable, i, currEntry - i);
valueTable[currEntry] = null;
// Remove the hash entry
int hash = hash(keyTable[i], 0, keyTable[i].length);
if (hashTable[hash] == i + 1)
hashTable[hash] = nextTable[i];
else {
// find entry pointing to me
int j = hashTable[hash] - 1;
while (nextTable[j] != 0 && nextTable[j] != i + 1)
j = nextTable[j] - 1;
nextTable[j] = nextTable[i];
}
if (i < currEntry) {
// shift everything over
System.arraycopy(keyTable, i + 1, keyTable, i, currEntry - i);
System.arraycopy(nextTable, i + 1, nextTable, i, currEntry - i);
// adjust hash and next entries for things that moved
for (int j = 0; j < hashTable.length; ++j)
if (hashTable[j] > i + 1)
--hashTable[j];
for (int j = 0; j < nextTable.length; ++j)
if (nextTable[j] > i + 1)
--nextTable[j];
}
// last entry is now free
keyTable[currEntry] = null;
nextTable[currEntry] = 0;
--currEntry;
}
private int lookup(char[] buffer, int start, int len) {
int hash = hash(buffer, start, len);
if (hashTable[hash] == 0)
return -1;
int i = hashTable[hash] - 1;
if (CharArrayUtils.equals(buffer, start, len, keyTable[i]))
return i;
// Follow the next chain
for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1)
if (CharArrayUtils.equals(buffer, start, len, keyTable[i]))
return i;
return -1;
}
private void quickSort( Comparator c, int p, int r ){
if( p < r ){
int q = partition( c, p, r );
if( p < q ) quickSort( c, p, q );
if( ++q < r ) quickSort( c, q, r );
}
}
private int partition( Comparator c, int p, int r ){
protected int partition( Comparator c, int p, int r ){
char[] x = keyTable[ p ];
Object temp = null;
int i = p;
@ -336,5 +130,4 @@ public class CharArrayObjectMap {//extends CharArrayMap {
}
}
}
}

View file

@ -22,58 +22,15 @@ package org.eclipse.cdt.internal.core.parser.scanner2;
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class CharArrayPool {
private int currEntry = -1;
// Hash table is twice the size of the others
private int[] hashTable;
private int[] nextTable;
private char[][] stringTable;
public class CharArrayPool extends CharTable{
public CharArrayPool(int tableSize) {
// make sure size is a power of 2
int size = 1;
while (size < tableSize)
size <<= 1;
hashTable = new int[size << 1];
nextTable = new int[tableSize];
stringTable = new char[tableSize][];
}
private final int hash(char[] source, int start, int length) {
return CharArrayUtils.hash(source, start, length) & (hashTable.length - 1);
}
private static final boolean equals(char[] str1, int start, int length, char[] str2) {
if (str2.length != length)
return false;
int curr = start;
for (int i = 0; i < length; ++i)
if (str1[curr++] != str2[i])
return false;
return true;
}
private final char[] find(char[] source, int start, int length, int hash) {
int i = hashTable[hash] - 1;
do {
char[] str = stringTable[i];
if (equals(source, start, length, str))
return str;
i = nextTable[i] - 1;
} while (i >= 0);
return null;
super(tableSize);
}
// Removes the current entry
private final void remove() {
int hash = hash(stringTable[currEntry], 0, stringTable[currEntry].length);
int hash = hash(keyTable[currEntry], 0, keyTable[currEntry].length);
int i = hashTable[hash] - 1;
if (i == currEntry)
// make my next the hash entry
@ -89,19 +46,19 @@ public class CharArrayPool {
nextTable[last] = nextTable[currEntry];
}
stringTable[currEntry] = null;
keyTable[currEntry] = null;
nextTable[currEntry] = 0;
}
private final void addHashed(char[] str, int hash) {
// First remove the existing string if there is one
if (++currEntry == stringTable.length)
if (++currEntry == keyTable.length)
currEntry = 0;
if (stringTable[currEntry] != null)
if (keyTable[currEntry] != null)
remove();
stringTable[currEntry] = str;
keyTable[currEntry] = str;
// Now add it to the hash table, insert into next entries as necessary
if (hashTable[hash] != 0)
@ -112,17 +69,16 @@ public class CharArrayPool {
public final char[] add(char[] source, int start, int length) {
// do we have it already?
int hash = hash(source, start, length);
char[] result = null;
if (hashTable[hash] > 0)
result = find(source, start, length, hash);
// if not, add it
if (result == null) {
System.arraycopy(source, 0, result = new char[length], 0, length);
addHashed(result, hash);
}
int result = lookup(source, start, length, hash);
return result;
if( result >= 0)
return keyTable[result];
char [] res = new char[length];
System.arraycopy(source, 0, res, 0, length);
addHashed(res, hash);
return res;
}
public final char[] add(char[] source) {

View file

@ -14,19 +14,13 @@
*/
package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author aniefer
*/
public class CharArraySet {
private char[][] keyTable;
private int[] hashTable;
private int[] nextTable;
private int currEntry = -1;
public class CharArraySet extends CharTable {
public static final CharArraySet EMPTY_SET = new CharArraySet( 0 ){
public Object clone() { return this; }
@ -37,17 +31,11 @@ public class CharArraySet {
};
public CharArraySet(int initialSize) {
int size = 1;
while (size < initialSize)
size <<= 1;
keyTable = new char[size][];
hashTable = new int[size * 2];
nextTable = new int[size];
super(initialSize);
}
public void put(char[] key ){
add(key);
addIndex(key);
}
public void addAll( List list ){
@ -56,7 +44,7 @@ public class CharArraySet {
int size = list.size();
for( int i = 0; i < size; i++ ){
add( (char[]) list.get( i ) );
addIndex( (char[]) list.get( i ) );
}
}
@ -65,18 +53,9 @@ public class CharArraySet {
return;
int size = set.size();
for( int i = 0; i < size; i++ ){
add( set.keyAt( i ) );
addIndex( set.keyAt( i ) );
}
}
public List toList(){
List list = new ArrayList( size() );
int size = size();
for( int i = 0; i < size; i++ ){
list.add( keyAt( i ) );
}
return list;
}
final public boolean remove( char[] key ) {
int i = lookup(key);
@ -87,55 +66,6 @@ public class CharArraySet {
return true;
}
/**
* @return
*/
final public boolean isEmpty() {
return currEntry == -1;
}
// public Object clone(){
// HashTable newTable = null;
// try {
// newTable = (HashTable) super.clone();
// } catch ( CloneNotSupportedException e ) {
// //shouldn't happen because object supports clone.
// return null;
// }
//
// int size = capacity();
// newTable.keyTable = new Object[ size ];
// newTable.hashTable = new int[ size*2 ];
// newTable.nextTable = new int[ size ];
//
// System.arraycopy(keyTable, 0, newTable.keyTable, 0, keyTable.length);
// System.arraycopy(hashTable, 0, newTable.hashTable, 0, hashTable.length);
// System.arraycopy(nextTable, 0, newTable.nextTable, 0, nextTable.length);
//
// newTable.currEntry = currEntry;
// return newTable;
// }
final public int size(){
return currEntry + 1;
}
final public char[] keyAt( int i ){
if( i < 0 || i > currEntry )
return null;
return keyTable[ i ];
}
final public boolean containsKey( char[] key ){
return lookup( key ) != -1;
}
// public Object [] keyArray(){
// Object [] keys = new Object[ size() ];
// System.arraycopy( keyTable, 0, keys, 0, keys.length );
// return keys;
// }
final public void clear(){
for( int i = 0; i < keyTable.length; i++ ){
keyTable[i] = null;
@ -145,151 +75,4 @@ public class CharArraySet {
}
currEntry = -1;
}
final public int capacity() {
return keyTable.length;
}
private int hash( char[] obj ){
return CharArrayUtils.hash( obj ) & (hashTable.length - 1);
}
private void insert(int i) {
insert(i, hash(keyTable[i]));
}
private void insert(int i, int hash) {
if (hashTable[hash] == 0) {
hashTable[hash] = i + 1;
} else {
// need to link
int j = hashTable[hash] - 1;
while (nextTable[j] != 0)
j = nextTable[j] - 1;
nextTable[j] = i + 1;
}
}
private void resize(int size) {
Object[] oldKeyTable = keyTable;
keyTable = new char[size][];
System.arraycopy(oldKeyTable, 0, keyTable, 0, oldKeyTable.length);
// Need to rehash everything
rehash( oldKeyTable.length, true );
}
private void rehash( int n, boolean reallocate ){
if( reallocate ){
hashTable = new int[ keyTable.length * 2 ];
nextTable = new int[ keyTable.length ];
} else {
for( int i = 0; i < keyTable.length; i++ ){
hashTable[2*i] = 0;
hashTable[2*i+1] = 0;
nextTable[i] = 0;
}
}
for (int i = 0; i < n; ++i) {
insert(i);
}
}
private void resize() {
resize(keyTable.length << 1);
}
private int add(char[] obj) {
int hash = hash(obj);
if (hashTable[hash] == 0) {
if ( (currEntry + 1) >= keyTable.length){
resize();
//hash code needs to be recomputed, just recurse.
return add( obj );
}
currEntry++;
keyTable[currEntry] = obj;
insert(currEntry, hash);
return currEntry;
}
// is the key already registered?
int i = hashTable[hash] - 1;
if ( CharArrayUtils.equals( obj, keyTable[i] ) )
// yup
return i;
// follow the next chain
int last = i;
for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1) {
if ( CharArrayUtils.equals( obj, keyTable[i] ) )
// yup this time
return i;
last = i;
}
// nope, add it in
if ( (currEntry + 1) >= keyTable.length){
resize();
//hash code needs to be recomputed, just recurse.
return add( obj );
}
currEntry++;
keyTable[currEntry] = obj;
nextTable[last] = currEntry + 1;
return currEntry;
}
private void removeEntry(int i) {
// Remove the hash entry
int hash = hash(keyTable[i]);
if (hashTable[hash] == i + 1)
hashTable[hash] = nextTable[i];
else {
// find entry pointing to me
int j = hashTable[hash] - 1;
while (nextTable[j] != 0 && nextTable[j] != i + 1)
j = nextTable[j] - 1;
nextTable[j] = nextTable[i];
}
if (i < currEntry) {
// shift everything over
System.arraycopy(keyTable, i + 1, keyTable, i, currEntry - i);
System.arraycopy(nextTable, i + 1, nextTable, i, currEntry - i);
// adjust hash and next entries for things that moved
for (int j = 0; j < hashTable.length; ++j)
if (hashTable[j] > i + 1)
--hashTable[j];
for (int j = 0; j < nextTable.length; ++j)
if (nextTable[j] > i + 1)
--nextTable[j];
}
// last entry is now free
keyTable[currEntry] = null;
nextTable[currEntry] = 0;
--currEntry;
}
private int lookup(char[] buffer ){
int hash = hash(buffer);
if (hashTable[hash] == 0)
return -1;
int i = hashTable[hash] - 1;
if ( CharArrayUtils.equals( buffer, keyTable[i] ) )
return i;
// Follow the next chain
for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1)
if ( CharArrayUtils.equals( buffer, keyTable[i] ) )
return i;
return -1;
}
}

View file

@ -9,91 +9,97 @@
* IBM Corporation - initial API and implementation
*******************************************************************************/
/*
* For use by the Parser Symbol Table
* Created on Jul 15, 2004
*/
package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.Comparator;
/**
* @author aniefer
* @author ddaoust
*/
public abstract class HashTable implements Cloneable{
protected Object[] keyTable;
private int[] hashTable;
private int[] nextTable;
public class HashTable {
protected static final int minHashSize = 2;
protected int currEntry = -1;
public boolean isEmpty() {
return currEntry == -1;
}
final public int size(){
return currEntry + 1;
}
protected int[] hashTable;
protected int[] nextTable;
public HashTable(int initialSize) {
int size = 1;
while (size < initialSize)
size <<= 1;
keyTable = new Object[size];
hashTable = new int[size * 2];
nextTable = new int[size];
if (size > minHashSize) {
hashTable = new int[size * 2];
nextTable = new int[size];
}
else {
hashTable = null;
nextTable = null;
}
}
protected void resize() {
resize(capacity() << 1);
}
public Object clone(){
HashTable newTable = null;
try {
newTable = (HashTable) super.clone();
} catch ( CloneNotSupportedException e ) {
//shouldn't happen because object supports clone.
return null;
}
int size = capacity();
newTable.keyTable = new Object[ size ];
newTable.hashTable = new int[ size*2 ];
newTable.nextTable = new int[ size ];
System.arraycopy(keyTable, 0, newTable.keyTable, 0, keyTable.length);
System.arraycopy(hashTable, 0, newTable.hashTable, 0, hashTable.length);
System.arraycopy(nextTable, 0, newTable.nextTable, 0, nextTable.length);
newTable.currEntry = currEntry;
return newTable;
}
public int size(){
return currEntry + 1;
}
public Object keyAt( int i ){
if( i < 0 || i > currEntry )
return null;
return keyTable[ i ];
}
public void clear(){
for( int i = 0; i < keyTable.length; i++ ){
keyTable[i] = null;
hashTable[ 2*i ] = 0;
hashTable[ 2*i + 1 ] = 0;
public void clear() {
currEntry = -1;
// clear the table
if (hashTable == null)
return;
for( int i = 0; i < capacity(); i++ ){
hashTable[2*i] = 0;
hashTable[2*i+1] = 0;
nextTable[i] = 0;
}
currEntry = -1;
}
}
protected void rehash() {
if (nextTable == null)
return;
// clear the table (don't call clear() or else the subclasses stuff will be cleared too)
for( int i = 0; i < capacity(); i++ ){
hashTable[2*i] = 0;
hashTable[2*i+1] = 0;
nextTable[i] = 0;
}
// Need to rehash everything
for (int i = 0; i <= currEntry; ++i) {
linkIntoHashTable(i, hash(i));
}
}
protected void resize(int size) {
if (size > minHashSize) {
hashTable = new int[size * 2];
nextTable = new int[size];
// Need to rehash everything
for (int i = 0; i <= currEntry; ++i) {
linkIntoHashTable(i, hash(i));
}
}
}
public int capacity() {
return keyTable.length;
protected int hash(int pos) {
// return the hash value of the element in the key table
throw new UnsupportedOperationException();
}
private int hash(Object obj) {
return obj.hashCode() & (hashTable.length - 1);
}
private void insert(int i) {
insert(i, hash(keyTable[i]));
}
private void insert(int i, int hash) {
protected void linkIntoHashTable(int i, int hash) {
if (nextTable == null)
return;
if (hashTable[hash] == 0) {
hashTable[hash] = i + 1;
@ -106,79 +112,19 @@ public abstract class HashTable implements Cloneable{
}
}
protected void resize(int size) {
Object[] oldKeyTable = keyTable;
keyTable = new Object[size];
System.arraycopy(oldKeyTable, 0, keyTable, 0, oldKeyTable.length);
// Need to rehash everything
rehash( oldKeyTable.length, true );
final public int capacity() {
if (nextTable == null)
return minHashSize;
return nextTable.length;
}
protected void rehash( int n, boolean reallocate ){
if( reallocate ){
hashTable = new int[ keyTable.length * 2 ];
nextTable = new int[ keyTable.length ];
} else {
for( int i = 0; i < keyTable.length; i++ ){
hashTable[2*i] = 0;
hashTable[2*i+1] = 0;
nextTable[i] = 0;
}
}
for (int i = 0; i < n; ++i) {
insert(i);
}
}
private void resize() {
resize(keyTable.length << 1);
}
protected final int add(Object obj) {
int hash = hash(obj);
if (hashTable[hash] == 0) {
if ( (currEntry + 1) >= keyTable.length){
resize();
//hash code needs to be recomputed, just recurse.
return add( obj );
}
currEntry++;
keyTable[currEntry] = obj;
insert(currEntry, hash);
return currEntry;
}
// is the key already registered?
int i = hashTable[hash] - 1;
if ( obj.equals( keyTable[i] ) )
// yup
return i;
// follow the next chain
int last = i;
for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1) {
if (obj.equals( keyTable[i] ) )
// yup this time
return i;
last = i;
protected void removeEntry(int i, int hash) {
if (nextTable == null){
--currEntry;
return;
}
// nope, add it in
if ( (currEntry + 1) >= keyTable.length){
resize();
//hash code needs to be recomputed, just recurse.
return add( obj );
}
currEntry++;
keyTable[currEntry] = obj;
nextTable[last] = currEntry + 1;
return currEntry;
}
protected void removeEntry(int i) {
// Remove the hash entry
int hash = hash(keyTable[i]);
if (hashTable[hash] == i + 1)
hashTable[hash] = nextTable[i];
else {
@ -191,7 +137,6 @@ public abstract class HashTable implements Cloneable{
if (i < currEntry) {
// shift everything over
System.arraycopy(keyTable, i + 1, keyTable, i, currEntry - i);
System.arraycopy(nextTable, i + 1, nextTable, i, currEntry - i);
// adjust hash and next entries for things that moved
@ -205,36 +150,42 @@ public abstract class HashTable implements Cloneable{
}
// last entry is now free
keyTable[currEntry] = null;
nextTable[currEntry] = 0;
--currEntry;
}
protected final int lookup(Object buffer ){
int hash = hash(buffer);
final public void sort( Comparator c ) {
if( size() > 1 ){
quickSort( c, 0, size() - 1 );
rehash();
}
}
final private void quickSort( Comparator c, int p, int r ){
if( p < r ){
int q = partition( c, p, r );
if( p < q ) quickSort( c, p, q );
if( ++q < r ) quickSort( c, q, r );
}
}
protected int partition( Comparator c, int p, int r ) {
throw new UnsupportedOperationException();
}
public void dumpNexts() {
if (nextTable == null)
return;
if (hashTable[hash] == 0)
return -1;
int i = hashTable[hash] - 1;
if (buffer.equals( keyTable[i] ) )
return i;
// Follow the next chain
for (i = nextTable[i] - 1; i >= 0; i = nextTable[i] - 1)
if ( buffer.equals( keyTable[i] ))
return i;
for (int i = 0; i < nextTable.length; ++i) {
if (nextTable[i] == 0)
continue;
return -1;
}
public boolean containsKey( Object key ){
return lookup( key ) != -1;
}
public Object [] keyArray(){
Object [] keys = new Object[ size() ];
System.arraycopy( keyTable, 0, keys, 0, keys.length );
return keys;
System.out.print(i);
for (int j = nextTable[i] - 1; j >= 0; j = nextTable[j] - 1)
System.out.print(" -> " + j); //$NON-NLS-1$
System.out.println(""); //$NON-NLS-1$
}
}
}

View file

@ -15,14 +15,17 @@
*/
package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* @author aniefer
*/
public class ObjectMap extends HashTable{
public class ObjectMap extends ObjectTable {
public static final ObjectMap EMPTY_MAP = new ObjectMap( 0 ){
public Object clone() { return this; }
public List toList() { return Collections.EMPTY_LIST; }
public Object put( Object key, Object value ) { throw new UnsupportedOperationException(); }
};
@ -30,15 +33,12 @@ public class ObjectMap extends HashTable{
public ObjectMap(int initialSize) {
super( initialSize );
valueTable = new Object[ capacity() ];
}
public Object clone(){
ObjectMap newMap = (ObjectMap) super.clone();
newMap.valueTable = new Object[ capacity() ];
System.arraycopy(valueTable, 0, newMap.valueTable, 0, valueTable.length);
return newMap;
}
@ -54,7 +54,6 @@ public class ObjectMap extends HashTable{
Object[] oldValueTable = valueTable;
valueTable = new Object[size];
System.arraycopy(oldValueTable, 0, valueTable, 0, oldValueTable.length);
super.resize( size );
}
@ -76,13 +75,8 @@ public class ObjectMap extends HashTable{
if( i < 0 || i > currEntry )
return null;
// return get( keyAt( i ) );
return valueTable[i];
}
final public boolean isEmpty(){
return currEntry == -1;
}
final public Object remove( Object key ) {
if( key == null )
@ -107,22 +101,7 @@ public class ObjectMap extends HashTable{
super.removeEntry(i);
}
final public void sort( Comparator c ) {
if( size() > 1 ){
quickSort( c, 0, size() - 1 );
rehash( size(), false );
}
}
private void quickSort( Comparator c, int p, int r ){
if( p < r ){
int q = partition( c, p, r );
if( p < q ) quickSort( c, p, q );
if( ++q < r ) quickSort( c, q, r );
}
}
private int partition( Comparator c, int p, int r ){
protected int partition( Comparator c, int p, int r ){
Object x = keyTable[ p ];
Object temp = null;
int i = p;

View file

@ -14,14 +14,13 @@
*/
package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author aniefer
*/
public class ObjectSet extends HashTable{
public class ObjectSet extends ObjectTable {
public static final ObjectSet EMPTY_SET = new ObjectSet( 0 ){
public Object clone() { return this; }
public List toList() { return Collections.EMPTY_LIST; }
@ -57,15 +56,6 @@ public class ObjectSet extends HashTable{
}
}
public List toList(){
List list = new ArrayList( size() );
int size = size();
for( int i = 0; i < size; i++ ){
list.add( keyAt( i ) );
}
return list;
}
public boolean remove( Object key ) {
int i = lookup(key);
if (i < 0)
@ -74,11 +64,4 @@ public class ObjectSet extends HashTable{
removeEntry(i);
return true;
}
/**
* @return
*/
public boolean isEmpty() {
return currEntry == -1;
}
}

View file

@ -85,7 +85,7 @@ public class Scanner2 implements IScanner, IScannerData {
protected IParserLogService log;
private IScannerExtension scannerExtension;
private CharArrayObjectMap definitions = new CharArrayObjectMap(64);
private CharArrayObjectMap definitions = new CharArrayObjectMap(512);
private String[] includePaths;
int count;