diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/ObjectMapTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/ObjectMapTest.java index 0f894746144..b75a9ed473b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/ObjectMapTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/ObjectMapTest.java @@ -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$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java index 7787da46959..baa0c1d1cdb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ContainerSymbol.java @@ -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; }; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java index 196b40410c2..dca31d4f5d6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java @@ -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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayIntMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayIntMap.java index 54803c5c90a..f6a8f0c7c00 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayIntMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayIntMap.java @@ -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; } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayMap.java deleted file mode 100644 index 851ad3bc2ab..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayMap.java +++ /dev/null @@ -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$ - } - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayObjectMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayObjectMap.java index 863a00a7ece..e9a0e66b8de 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayObjectMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayObjectMap.java @@ -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 { } } } - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayPool.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayPool.java index 00855ef6723..9836c5bb7aa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayPool.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArrayPool.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArraySet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArraySet.java index 1e38478d067..d21ffd22fcd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArraySet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/CharArraySet.java @@ -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; - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/HashTable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/HashTable.java index 7cc6d50c31d..091ecb2a080 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/HashTable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/HashTable.java @@ -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$ + } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectMap.java index ed97f76734c..72ad47f0582 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectMap.java @@ -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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectSet.java index f4f9582cc6d..f92c447b218 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/ObjectSet.java @@ -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; - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java index d7096a5c46e..90b08222a0f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/Scanner2.java @@ -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;