1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-01 20:53:12 +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 ); ObjectMap map = new ObjectMap( 1 );
assertEquals( map.size(), 0 ); assertEquals( map.size(), 0 );
assertEquals( map.capacity(), 1 ); assertEquals( map.capacity(), 2 );
Object [][] res = new Object [][] { { "0", "o0" }, //$NON-NLS-1$//$NON-NLS-2$ Object [][] res = new Object [][] { { "0", "o0" }, //$NON-NLS-1$//$NON-NLS-2$
{ "1", "o1" }, //$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 ); ObjectMap map = new ObjectMap( 1 );
assertEquals( map.size(), 0 ); assertEquals( map.size(), 0 );
assertEquals( map.capacity(), 1 ); assertEquals( map.capacity(), 2 );
Object [][] res = new Object [][] { { new HashObject(0), "o0" }, //$NON-NLS-1$ Object [][] res = new Object [][] { { new HashObject(0), "o0" }, //$NON-NLS-1$
{ new HashObject(1), "o1" }, //$NON-NLS-1$ { new HashObject(1), "o1" }, //$NON-NLS-1$
@ -115,7 +115,7 @@ public class ObjectMapTest extends TestCase {
ObjectMap map = new ObjectMap( 1 ); ObjectMap map = new ObjectMap( 1 );
assertEquals( map.size(), 0 ); assertEquals( map.size(), 0 );
assertEquals( map.capacity(), 1 ); assertEquals( map.capacity(), 2 );
Object [][] res = new Object [][] { { "0", "o0" }, //$NON-NLS-1$ //$NON-NLS-2$ Object [][] res = new Object [][] { { "0", "o0" }, //$NON-NLS-1$ //$NON-NLS-2$
{ "1", "o1" } }; //$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{ 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 //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 //during the normal lookup to avoid doing them twice
final ObjectSet associated = new ObjectSet(0); ObjectSet associated = ObjectSet.EMPTY_SET;
//collect associated namespaces & classes. //collect associated namespaces & classes.
int size = ( parameters == null ) ? 0 : parameters.size(); int size = ( parameters == null ) ? 0 : parameters.size();
@ -683,6 +683,8 @@ public class ContainerSymbol extends BasicSymbol implements IContainerSymbol {
continue; continue;
} }
if( associated == ObjectSet.EMPTY_SET )
associated = new ObjectSet( 2 );
ParserSymbolTable.getAssociatedScopes( paramType, associated ); ParserSymbolTable.getAssociatedScopes( paramType, associated );
//if T is a pointer to a data member of class X, its associated namespaces and classes //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 ){ LookupData data = new LookupData( name ){
public ObjectSet getAssociated() { return assoc; } public ObjectSet getAssociated() { return assoc; }
public List getParameters() { return params; } public List getParameters() { return params; }
public TypeFilter getFilter() { return FUNCTION_FILTER; } 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; 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 //namespaces are searched at most once
if( !data.visited.containsKey( temp ) ){ if( !data.visited.containsKey( temp ) ){
if( data.visited == ObjectSet.EMPTY_SET )
data.visited = new ObjectSet( 2 );
data.visited.put( temp ); data.visited.put( temp );
CharArrayObjectMap map = lookupInContained( data, temp ); CharArrayObjectMap map = lookupInContained( data, temp );
@ -658,6 +660,8 @@ public class ParserSymbolTable {
if( !wrapper.isVirtual() || !data.visited.containsKey( parent ) ){ if( !wrapper.isVirtual() || !data.visited.containsKey( parent ) ){
if( wrapper.isVirtual() ){ if( wrapper.isVirtual() ){
if( data.visited == ObjectSet.EMPTY_SET )
data.visited = new ObjectSet(2);
data.visited.put( parent ); data.visited.put( parent );
} }
@ -2219,7 +2223,7 @@ public class ParserSymbolTable {
public char[] name; public char[] name;
public ObjectMap usingDirectives; 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 ObjectSet inheritanceChain; //used to detect circular inheritance
public ISymbol templateMember; //to assit with template member defs 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 * @author Doug Schaefer
*/ */
public class CharArrayIntMap extends CharArrayMap { public class CharArrayIntMap extends CharTable {
private int[] valueTable; private int[] valueTable;
public final int undefined; public final int undefined;
@ -28,10 +28,16 @@ public class CharArrayIntMap extends CharArrayMap {
int[] oldValueTable = valueTable; int[] oldValueTable = valueTable;
valueTable = new int[size]; valueTable = new int[size];
System.arraycopy(oldValueTable, 0, valueTable, 0, oldValueTable.length); 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) { 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]; int oldvalue = valueTable[i];
valueTable[i] = value; valueTable[i] = value;
return oldvalue; return oldvalue;
@ -45,7 +51,6 @@ public class CharArrayIntMap extends CharArrayMap {
int i = lookup(key, start, length); int i = lookup(key, start, length);
if (i >= 0) if (i >= 0)
return valueTable[i]; 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; package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List;
/** /**
* @author Doug Schaefer * @author Doug Schaefer
*/ */
public class CharArrayObjectMap {//extends CharArrayMap { public class CharArrayObjectMap extends CharTable {
public static final CharArrayObjectMap EMPTY_MAP = new CharArrayObjectMap( 0 ){ public static final CharArrayObjectMap EMPTY_MAP = new CharArrayObjectMap( 0 ){
public Object clone() { return this; } public Object clone() { return this; }
public List toList() { return Collections.EMPTY_LIST; }
public Object put( char[] key, int start, int length, Object value ) public Object put( char[] key, int start, int length, Object value )
{ throw new UnsupportedOperationException(); } { throw new UnsupportedOperationException(); }
}; };
private char[][] keyTable;
private int[] hashTable;
private int[] nextTable;
private Object[] valueTable; private Object[] valueTable;
private int currEntry = -1;
public CharArrayObjectMap(int initialSize) { public CharArrayObjectMap(int initialSize) {
int size = 1; super(initialSize);
while (size < initialSize) valueTable = new Object[capacity()];
size <<= 1;
keyTable = new char[size][];
hashTable = new int[size * 2];
nextTable = new int[size];
valueTable = new Object[size];
} }
public Object put(char[] key, int start, int length, Object value) { 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]; Object oldvalue = valueTable[i];
valueTable[i] = value; valueTable[i] = value;
return oldvalue; return oldvalue;
@ -65,21 +57,9 @@ public class CharArrayObjectMap {//extends CharArrayMap {
final public Object getAt( int i ){ final public Object getAt( int i ){
if( i < 0 || i > currEntry ) if( i < 0 || i > currEntry )
return null; return null;
// char [] key = keyAt( i );
// if( key == null ) return null;
//
// return get( key, 0, key.length );
return valueTable[i]; 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) { final public Object remove(char[] key, int start, int length) {
int i = lookup(key, start, length); int i = lookup(key, start, length);
if (i < 0) if (i < 0)
@ -87,232 +67,46 @@ public class CharArrayObjectMap {//extends CharArrayMap {
Object value = valueTable[i]; Object value = valueTable[i];
if (i < currEntry)
System.arraycopy(valueTable, i + 1, valueTable, i, currEntry - i);
valueTable[currEntry] = null;
removeEntry(i); removeEntry(i);
return value; return value;
} }
final public Object remove(char[] key) {
return remove(key, 0, key.length);
}
public Object clone(){ public Object clone(){
int size = capacity(); int size = capacity();
CharArrayObjectMap newTable = new CharArrayObjectMap( size ); 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(valueTable, 0, newTable.valueTable, 0, valueTable.length);
System.arraycopy(keyTable, 0, newTable.keyTable, 0, keyTable.length); System.arraycopy(keyTable, 0, newTable.keyTable, 0, keyTable.length);
System.arraycopy(hashTable, 0, newTable.hashTable, 0, hashTable.length); if( hashTable != null )
System.arraycopy(nextTable, 0, newTable.nextTable, 0, nextTable.length); System.arraycopy(hashTable, 0, newTable.hashTable, 0, hashTable.length);
if( nextTable != null )
System.arraycopy(nextTable, 0, newTable.nextTable, 0, nextTable.length);
newTable.currEntry = currEntry; newTable.currEntry = currEntry;
return newTable; return newTable;
} }
final public int size(){ protected void resize(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) {
Object[] oldValueTable = valueTable; Object[] oldValueTable = valueTable;
valueTable = new Object[size]; valueTable = new Object[size];
System.arraycopy(oldValueTable, 0, valueTable, 0, oldValueTable.length); System.arraycopy(oldValueTable, 0, valueTable, 0, oldValueTable.length);
super.resize(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 int hash(char[] buffer, int start, int len) { public void clear() {
return CharArrayUtils.hash(buffer, start, len) & (hashTable.length - 1); super.clear();
} for( int i = 0; i < capacity(); i++ )
valueTable[i] = null;
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;
}
} }
private void rehash( int n, boolean reallocate ){ protected int partition( Comparator c, int p, int r ){
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 ){
char[] x = keyTable[ p ]; char[] x = keyTable[ p ];
Object temp = null; Object temp = null;
int i = p; 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 * TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates * Window - Preferences - Java - Code Style - Code Templates
*/ */
public class CharArrayPool { public class CharArrayPool extends CharTable{
private int currEntry = -1;
// Hash table is twice the size of the others
private int[] hashTable;
private int[] nextTable;
private char[][] stringTable;
public CharArrayPool(int tableSize) { public CharArrayPool(int tableSize) {
// make sure size is a power of 2 super(tableSize);
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;
} }
// Removes the current entry // Removes the current entry
private final void remove() { 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; int i = hashTable[hash] - 1;
if (i == currEntry) if (i == currEntry)
// make my next the hash entry // make my next the hash entry
@ -89,19 +46,19 @@ public class CharArrayPool {
nextTable[last] = nextTable[currEntry]; nextTable[last] = nextTable[currEntry];
} }
stringTable[currEntry] = null; keyTable[currEntry] = null;
nextTable[currEntry] = 0; nextTable[currEntry] = 0;
} }
private final void addHashed(char[] str, int hash) { private final void addHashed(char[] str, int hash) {
// First remove the existing string if there is one // First remove the existing string if there is one
if (++currEntry == stringTable.length) if (++currEntry == keyTable.length)
currEntry = 0; currEntry = 0;
if (stringTable[currEntry] != null) if (keyTable[currEntry] != null)
remove(); remove();
stringTable[currEntry] = str; keyTable[currEntry] = str;
// Now add it to the hash table, insert into next entries as necessary // Now add it to the hash table, insert into next entries as necessary
if (hashTable[hash] != 0) if (hashTable[hash] != 0)
@ -112,17 +69,16 @@ public class CharArrayPool {
public final char[] add(char[] source, int start, int length) { public final char[] add(char[] source, int start, int length) {
// do we have it already? // do we have it already?
int hash = hash(source, start, length); int hash = hash(source, start, length);
char[] result = null; int result = lookup(source, start, length, hash);
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);
}
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) { public final char[] add(char[] source) {

View file

@ -14,19 +14,13 @@
*/ */
package org.eclipse.cdt.internal.core.parser.scanner2; package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
* @author aniefer * @author aniefer
*/ */
public class CharArraySet { public class CharArraySet extends CharTable {
private char[][] keyTable;
private int[] hashTable;
private int[] nextTable;
private int currEntry = -1;
public static final CharArraySet EMPTY_SET = new CharArraySet( 0 ){ public static final CharArraySet EMPTY_SET = new CharArraySet( 0 ){
public Object clone() { return this; } public Object clone() { return this; }
@ -37,17 +31,11 @@ public class CharArraySet {
}; };
public CharArraySet(int initialSize) { public CharArraySet(int initialSize) {
int size = 1; super(initialSize);
while (size < initialSize)
size <<= 1;
keyTable = new char[size][];
hashTable = new int[size * 2];
nextTable = new int[size];
} }
public void put(char[] key ){ public void put(char[] key ){
add(key); addIndex(key);
} }
public void addAll( List list ){ public void addAll( List list ){
@ -56,7 +44,7 @@ public class CharArraySet {
int size = list.size(); int size = list.size();
for( int i = 0; i < size; i++ ){ 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; return;
int size = set.size(); int size = set.size();
for( int i = 0; i < size; i++ ){ 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 ) { final public boolean remove( char[] key ) {
int i = lookup(key); int i = lookup(key);
@ -87,55 +66,6 @@ public class CharArraySet {
return true; 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(){ final public void clear(){
for( int i = 0; i < keyTable.length; i++ ){ for( int i = 0; i < keyTable.length; i++ ){
keyTable[i] = null; keyTable[i] = null;
@ -145,151 +75,4 @@ public class CharArraySet {
} }
currEntry = -1; 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 * 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; package org.eclipse.cdt.internal.core.parser.scanner2;
import java.util.Comparator;
/** /**
* @author aniefer * @author ddaoust
*/ */
public abstract class HashTable implements Cloneable{ public class HashTable {
protected Object[] keyTable;
private int[] hashTable;
private int[] nextTable;
protected static final int minHashSize = 2;
protected int currEntry = -1; 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) { public HashTable(int initialSize) {
int size = 1; int size = 1;
while (size < initialSize) while (size < initialSize)
size <<= 1; size <<= 1;
keyTable = new Object[size]; if (size > minHashSize) {
hashTable = new int[size * 2]; hashTable = new int[size * 2];
nextTable = new int[size]; nextTable = new int[size];
}
else {
hashTable = null;
nextTable = null;
}
}
protected void resize() {
resize(capacity() << 1);
} }
public Object clone(){ public void clear() {
HashTable newTable = null; currEntry = -1;
try {
newTable = (HashTable) super.clone(); // clear the table
} catch ( CloneNotSupportedException e ) { if (hashTable == null)
//shouldn't happen because object supports clone. return;
return null;
} for( int i = 0; i < capacity(); i++ ){
hashTable[2*i] = 0;
int size = capacity(); hashTable[2*i+1] = 0;
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;
nextTable[i] = 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() { protected int hash(int pos) {
return keyTable.length; // return the hash value of the element in the key table
throw new UnsupportedOperationException();
} }
private int hash(Object obj) { protected void linkIntoHashTable(int i, int hash) {
return obj.hashCode() & (hashTable.length - 1); if (nextTable == null)
} return;
private void insert(int i) {
insert(i, hash(keyTable[i]));
}
private void insert(int i, int hash) {
if (hashTable[hash] == 0) { if (hashTable[hash] == 0) {
hashTable[hash] = i + 1; hashTable[hash] = i + 1;
@ -106,79 +112,19 @@ public abstract class HashTable implements Cloneable{
} }
} }
protected void resize(int size) { final public int capacity() {
Object[] oldKeyTable = keyTable; if (nextTable == null)
keyTable = new Object[size]; return minHashSize;
System.arraycopy(oldKeyTable, 0, keyTable, 0, oldKeyTable.length); return nextTable.length;
// Need to rehash everything
rehash( oldKeyTable.length, true );
} }
protected void rehash( int n, boolean reallocate ){ protected void removeEntry(int i, int hash) {
if( reallocate ){ if (nextTable == null){
hashTable = new int[ keyTable.length * 2 ]; --currEntry;
nextTable = new int[ keyTable.length ]; return;
} 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;
} }
// 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 // Remove the hash entry
int hash = hash(keyTable[i]);
if (hashTable[hash] == i + 1) if (hashTable[hash] == i + 1)
hashTable[hash] = nextTable[i]; hashTable[hash] = nextTable[i];
else { else {
@ -191,7 +137,6 @@ public abstract class HashTable implements Cloneable{
if (i < currEntry) { if (i < currEntry) {
// shift everything over // shift everything over
System.arraycopy(keyTable, i + 1, keyTable, i, currEntry - i);
System.arraycopy(nextTable, i + 1, nextTable, i, currEntry - i); System.arraycopy(nextTable, i + 1, nextTable, i, currEntry - i);
// adjust hash and next entries for things that moved // adjust hash and next entries for things that moved
@ -205,36 +150,42 @@ public abstract class HashTable implements Cloneable{
} }
// last entry is now free // last entry is now free
keyTable[currEntry] = null;
nextTable[currEntry] = 0; nextTable[currEntry] = 0;
--currEntry; --currEntry;
} }
protected final int lookup(Object buffer ){ final public void sort( Comparator c ) {
int hash = hash(buffer); 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) for (int i = 0; i < nextTable.length; ++i) {
return -1; if (nextTable[i] == 0)
continue;
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;
return -1; System.out.print(i);
}
for (int j = nextTable[i] - 1; j >= 0; j = nextTable[j] - 1)
public boolean containsKey( Object key ){ System.out.print(" -> " + j); //$NON-NLS-1$
return lookup( key ) != -1;
} System.out.println(""); //$NON-NLS-1$
}
public Object [] keyArray(){
Object [] keys = new Object[ size() ];
System.arraycopy( keyTable, 0, keys, 0, keys.length );
return keys;
} }
} }

View file

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

View file

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

View file

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