1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-02 22:55:26 +02:00

New character array utilities that should make things much faster, one day...

This commit is contained in:
Doug Schaefer 2004-05-28 20:53:35 +00:00
parent 764632f0c3
commit c839041374
4 changed files with 366 additions and 0 deletions

View file

@ -0,0 +1,97 @@
/*
* Created on May 28, 2004
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package org.eclipse.cdt.core.parser.tests;
import junit.framework.TestCase;
import org.eclipse.cdt.core.parser.CharArrayMap;
import org.eclipse.cdt.core.parser.CharArrayPool;
import org.eclipse.cdt.core.parser.CharArrayUtils;
/**
* @author dschaefe
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class CharArrayUtilsTest extends TestCase {
public void testPoolAdd() {
CharArrayPool dict = new CharArrayPool(1);
char[] str1 = new char[] {'h', 'e', 'l', 'l', 'o'};
char[] str2 = dict.add(str1);
assertTrue(CharArrayUtils.equals(str1, str2));
assertNotSame(str1, str2);
char[] str3 = dict.add(str1);
assertSame(str2, str3);
char[] str4 = new char[] {'w', 'o', 'r', 'l', 'd'};
char[] str5 = dict.add(str4, 0, str4.length);
assertTrue(CharArrayUtils.equals(str4, str5));
assertNotSame(str4, str5);
char[] str6 = dict.add(str4);
assertSame(str5, str6);
char[] str7 = dict.add(str1, 0, str1.length);
assertTrue(CharArrayUtils.equals(str1, str7));
assertNotSame(str1, str7);
char[] str8 = dict.add(str1);
assertSame(str7, str8);
}
public void testPoolConflict() {
CharArrayPool dict = new CharArrayPool(2);
char[] str1 = new char[] {'h', 'e', 'l', 'l', 'o'};
char[] str2 = dict.add(str1);
// The hash algorithm should give this the same hash code
char[] str3 = new char[] {'h', 'o', 'l', 'l', 'e'};
char[] str4 = dict.add(str3);
assertNotSame(str2, str4);
char[] str5 = dict.add(str1);
assertTrue(CharArrayUtils.equals(str1, str5));
char[] str6 = new char[] {'w', 'o', 'r', 'l', 'd'};
char[] str7 = dict.add(str6);
assertTrue(CharArrayUtils.equals(str6, str7));
char[] str8 = dict.add(str3);
assertSame(str4, str8);
char[] str9 = dict.add(str1);
assertNotSame(str2, str9);
// This should be the same since the removals are done by addition time,
// not access time
char[] str10 = dict.add(str6);
assertSame(str7, str10);
}
public void testMapAdd() {
CharArrayMap map = new CharArrayMap(4);
char[] key1 = "key1".toCharArray();
Object value1 = new Integer(43);
map.put(key1, value1);
char[] key2 = "key1".toCharArray();
Object value2 = map.get(key2);
assertEquals(value1, value2);
for (int i = 0; i < 5; ++i) {
map.put(("ikey" + i).toCharArray(), new Integer(i));
}
Object ivalue1 = map.get("ikey1".toCharArray());
assertEquals(ivalue1, new Integer(1));
Object ivalue4 = map.get("ikey4".toCharArray());
assertEquals(ivalue4, new Integer(4));
}
}

View file

@ -0,0 +1,101 @@
/*
* Created on May 28, 2004
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package org.eclipse.cdt.core.parser;
/**
* @author dschaefe
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class CharArrayMap {
private char[][] keyTable;
private Object[] valueTable;
private int[] hashTable;
private int[] nextTable;
private int currEntry;
public CharArrayMap(int initialSize) {
// Make sure size is a power of two
int size = 1;
while (size < initialSize)
size <<= 1;
createTables(size);
}
private final void createTables(int size) {
keyTable = new char[size][];
valueTable = new Object[size];
nextTable = new int[size];
hashTable = new int[size << 1];
currEntry = 0;
}
private final int hash(char[] key) {
return CharArrayUtils.hash(key) & (hashTable.length - 1);
}
private final int add(char[] key, Object value) {
keyTable[currEntry] = key;
valueTable[currEntry] = value;
return ++currEntry;
}
// returns the overwritten object if there was one
public Object put(char[] key, Object value) {
try {
int hash = hash(key);
int i = hashTable[hash] - 1;
if (i < 0) {
// Nobody here
hashTable[hash] = add(key, value);
} else {
// See if the key is already defined
int last = i;
while (i >= 0) {
if (CharArrayUtils.equals(key, keyTable[i])) {
Object oldvalue = valueTable[i];
valueTable[i] = value;
// Nothing left to do, escape...
return oldvalue;
}
last = i;
i = nextTable[i] - 1;
}
// Not there, time to add
nextTable[last] = add(key, value);
}
return null;
} catch (IndexOutOfBoundsException e) {
// Oops, too many, resize and try again
char[][] oldKeyTable = keyTable;
Object[] oldValueTable = valueTable;
int newSize = hashTable.length << 1;
createTables(newSize);
for (int i = 0; i < oldKeyTable.length; ++i)
put(oldKeyTable[i], oldValueTable[i]);
return put(key, value);
}
}
public Object get(char[] key) {
int hash = hash(key);
int i = hashTable[hash] - 1;
while (i >= 0) {
if (CharArrayUtils.equals(key, keyTable[i]))
return valueTable[i];
i = nextTable[i] - 1;
}
return null;
}
}

View file

@ -0,0 +1,121 @@
/*
* Created on May 28, 2004
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package org.eclipse.cdt.core.parser;
/**
* @author dschaefe
*
* 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 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;
}
// Removes the current entry
private final void remove() {
int hash = hash(stringTable[currEntry], 0, stringTable[currEntry].length);
int i = hashTable[hash] - 1;
if (i == currEntry)
// make my next the hash entry
hashTable[hash] = nextTable[currEntry];
else {
// remove me from the next list
int last;
do {
last = i;
i = nextTable[i] - 1;
} while (i != currEntry);
nextTable[last] = nextTable[currEntry];
}
stringTable[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)
currEntry = 0;
if (stringTable[currEntry] != null)
remove();
stringTable[currEntry] = str;
// Now add it to the hash table, insert into next entries as necessary
if (hashTable[hash] != 0)
nextTable[currEntry] = hashTable[hash];
hashTable[hash] = currEntry + 1;
}
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);
}
return result;
}
public final char[] add(char[] source) {
return add(source, 0, source.length);
}
}

View file

@ -0,0 +1,47 @@
/*
* Created on May 28, 2004
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package org.eclipse.cdt.core.parser;
/**
* @author dschaefe
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class CharArrayUtils {
public static final int hash(char[] str, int start, int length) {
int h = 0;
int curr = start;
for (int i = length; i > 0; --i, curr++)
h += str[curr];
return h;
}
public static final int hash(char[] str) {
return hash(str, 0, str.length);
}
public static final boolean equals(char[] str1, char[] str2) {
if (str1 == str2)
return true;
if (str1 == null || str2 == null)
return false;
if (str1.length != str2.length)
return false;
for (int i = 0; i < str1.length; ++i)
if (str1[i] != str2[i])
return false;
return true;
}
}