1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Proper hashCode() for ShortString and LongString (bug 185343)

This commit is contained in:
Markus Schorn 2007-11-21 12:10:06 +00:00
parent 3a0b436262
commit 85042a14f6
3 changed files with 96 additions and 23 deletions

View file

@ -273,6 +273,16 @@ public class DBTest extends BaseTestCase {
IString aisc = db.newString(acs);
IString bisc = db.newString(bcs);
assertEquals(a.hashCode(), aiss.hashCode());
assertEquals(a.hashCode(), aisc.hashCode());
assertEquals(b.hashCode(), biss.hashCode());
assertEquals(b.hashCode(), bisc.hashCode());
assertEquals(aiss, a);
assertEquals(aisc, a);
assertEquals(biss, b);
assertEquals(bisc, b);
assertSignEquals(expected, aiss.compare(bcs, caseSensitive));
assertSignEquals(expected, aiss.compare(biss, caseSensitive));
assertSignEquals(expected, aiss.compare(bisc, caseSensitive));

View file

@ -15,7 +15,7 @@ package org.eclipse.cdt.internal.core.pdom.db;
import java.util.NoSuchElementException;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.core.runtime.CoreException;
/**
@ -28,7 +28,8 @@ import org.eclipse.core.runtime.CoreException;
public class LongString implements IString {
private final Database db;
private final int record1;
private final int record;
private int hash;
// Additional fields of first record
private static final int LENGTH = 0; // must be first to match ShortString
@ -43,9 +44,9 @@ public class LongString implements IString {
private static final int NUM_CHARSN = (Database.MAX_SIZE - CHARSN) / 2;
public LongString(Database db, int record1) {
public LongString(Database db, int record) {
this.db = db;
this.record1 = record1;
this.record = record;
}
private interface IWriter {
@ -81,7 +82,7 @@ public class LongString implements IString {
public LongString(Database db, final String string) throws CoreException {
this.db = db;
this.record1 = createString(string.length(), new IWriter() {
this.record = createString(string.length(), new IWriter() {
public void writeChars(int start, int length, int p) throws CoreException {
for (int i = start; i < start + length; ++i) {
LongString.this.db.putChar(p, string.charAt(i));
@ -93,7 +94,7 @@ public class LongString implements IString {
public LongString(Database db, final char[] chars) throws CoreException {
this.db = db;
this.record1 = createString(chars.length, new IWriter() {
this.record = createString(chars.length, new IWriter() {
public void writeChars(int start, int length, int p) throws CoreException {
for (int i = start; i < start + length; ++i) {
LongString.this.db.putChar(p, chars[i]);
@ -104,13 +105,13 @@ public class LongString implements IString {
}
public int getRecord() {
return record1;
return record;
}
public void delete() throws CoreException {
int length = db.getInt(record1 + LENGTH) - NUM_CHARS1;
int nextRecord = db.getInt(record1 + NEXT1);
db.free(record1);
int length = db.getInt(record + LENGTH) - NUM_CHARS1;
int nextRecord = db.getInt(record + NEXT1);
db.free(record);
// Middle records
while (length > NUM_CHARSN) {
@ -125,11 +126,57 @@ public class LongString implements IString {
}
public boolean equals(Object obj) {
throw new PDOMNotImplementedError();
if (obj == this)
return true;
try {
if (obj instanceof LongString) {
LongString lstr = (LongString)obj;
if (db == lstr.db && record == lstr.record)
return true;
return compare(lstr, true) == 0;
}
if (obj instanceof char[]) {
return compare((char[]) obj, true) == 0;
}
if (obj instanceof String) {
return compare((String) obj, true) == 0;
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
return false;
}
private class HashCodeComputer implements IReader {
private int fHashcode= 0;
public int getHashcode() {
return fHashcode;
}
public void appendChar(char c) {
fHashcode = 31*fHashcode + c;
}
}
/**
* Compatible with {@link String#hashCode()}
*/
public int hashCode() {
return record1;
int h = hash;
if (h == 0) {
HashCodeComputer hcc;
try {
int length = db.getInt(record + LENGTH);
hcc = new HashCodeComputer();
readChars(length, hcc);
h= hcc.getHashcode();
hash = h;
} catch (CoreException e) {
}
}
return h;
}
public int compare(IString string, boolean caseSensitive) throws CoreException {
@ -246,13 +293,13 @@ public class LongString implements IString {
private void readChars(int length, IReader reader) throws CoreException {
// First record
int p = record1 + CHARS1;
int p = record + CHARS1;
for (int i = 0; i < NUM_CHARS1; ++i) {
reader.appendChar(db.getChar(p));
p += 2;
}
length -= NUM_CHARS1;
int nextRecord = db.getInt(record1 + NEXT1);
int nextRecord = db.getInt(record + NEXT1);
// Middle records
while (length > NUM_CHARSN) {
@ -282,8 +329,8 @@ public class LongString implements IString {
int length;
public CharIterator() throws CoreException {
p = record1 + CHARS1;
length = db.getInt(record1 + LENGTH);
p = record + CHARS1;
length = db.getInt(record + LENGTH);
}
public char next() throws CoreException {
@ -294,10 +341,10 @@ public class LongString implements IString {
throw new NoSuchElementException();
}
if(count == NUM_CHARS1) {
p = db.getInt(record1 + NEXT1) + CHARSN;
p = db.getInt(record + NEXT1) + CHARSN;
}
if(count > NUM_CHARS1 && ((count-NUM_CHARS1) % NUM_CHARSN)==0) {
p = db.getInt(record1 + NEXTN) + CHARSN;
p = db.getInt(p-(NUM_CHARSN*2)-4) + CHARSN;
}
return result;
}
@ -308,7 +355,7 @@ public class LongString implements IString {
}
public char[] getChars() throws CoreException {
int length = db.getInt(record1 + LENGTH);
int length = db.getInt(record + LENGTH);
final char[] chars = new char[length];
readChars(length, new IReader() {
int cp = 0;
@ -320,7 +367,7 @@ public class LongString implements IString {
}
public String getString() throws CoreException {
int length = db.getInt(record1 + LENGTH);
int length = db.getInt(record + LENGTH);
final StringBuffer buffer = new StringBuffer(length);
readChars(length, new IReader() {
public void appendChar(char c) {

View file

@ -25,6 +25,7 @@ public class ShortString implements IString {
private final Database db;
private final int record;
private int hash;
private static final int LENGTH = 0;
private static final int CHARS = 4;
@ -152,9 +153,24 @@ public class ShortString implements IString {
return false;
}
/**
* Compatible with {@link String#hashCode()}
*/
public int hashCode() {
// Custom hash code function to allow DBStrings in hashmaps.
return record;
int h = hash;
if (h == 0) {
char chars[];
try {
chars = getChars();
final int len = chars.length;
for (int i = 0; i < len; i++) {
h = 31*h + chars[i];
}
} catch (CoreException e) {
}
hash = h;
}
return h;
}
public int compare(char[] other, boolean caseSensitive) throws CoreException {