1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Cleaned up the implementation of strings in the database. I now store the length instead of zero terminating. Should be faster. Also fixed a bug in the BTree visit routine that prevented nodes at the end from being visited.

This commit is contained in:
Doug Schaefer 2005-12-02 20:00:51 +00:00
parent 438433b2fd
commit 0324c8d8de
10 changed files with 138 additions and 249 deletions

View file

@ -7,8 +7,8 @@ import junit.framework.TestCase;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.StringComparator;
import org.eclipse.cdt.internal.core.pdom.db.StringVisitor;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@ -71,12 +71,18 @@ public class DBTest extends TestCase {
assertEquals(mem2, mem1);
}
private static class FindVisitor extends StringVisitor {
private static class FindVisitor implements IBTreeVisitor {
private Database db;
private String key;
private int record;
public FindVisitor(Database db, String key) {
super(db, Database.INT_SIZE, key);
this.db = db;
this.key = key;
}
public int compare(int record) throws CoreException {
return db.stringCompare(record + 4, key);
}
public boolean visit(int record) throws CoreException {
@ -95,7 +101,7 @@ public class DBTest extends TestCase {
// Tests inserting and retrieving strings
File f = getTestDir().append("testStrings.dat").toFile();
f.delete();
Database db = new Database(f.getCanonicalPath(), 0);
final Database db = new Database(f.getCanonicalPath(), 0);
String[] names = {
"ARLENE",
@ -129,7 +135,11 @@ public class DBTest extends TestCase {
int record = db.malloc((name.length() + 1) * Database.CHAR_SIZE + Database.INT_SIZE);
db.putInt(record, i);
db.putString(record + Database.INT_SIZE, name);
btree.insert(record, new StringComparator(db, Database.INT_SIZE));
btree.insert(record, new IBTreeComparator() {
public int compare(int record1, int record2) throws CoreException {
return db.stringCompare(record1 + 4, record2 + 4);
}
});
}
for (int i = 0; i < names.length; ++i) {

View file

@ -59,6 +59,6 @@ public class PDOMLanguage {
}
public boolean equals(String id) throws CoreException {
return PDOMUtils.stringCompare(pdom.getDB(), record + NAME, id) == 0;
return pdom.getDB().stringCompare(record + NAME, id) == 0;
}
}

View file

@ -1,104 +0,0 @@
/**
*
*/
package org.eclipse.cdt.internal.core.pdom;
import org.eclipse.cdt.internal.core.pdom.db.Chunk;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.core.runtime.CoreException;
/**
* @author dschaefer
*
*/
public class PDOMUtils {
public static int stringCompare(Database db, int record1, int record2) throws CoreException {
Chunk chunk1 = db.getChunk(record1);
Chunk chunk2 = db.getChunk(record2);
int i1 = record1;
int i2 = record2;
char c1 = chunk1.getChar(i1);
char c2 = chunk2.getChar(i2);
while (c1 != 0 && c2 != 0) {
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
i1 += 2;
i2 += 2;
c1 = chunk1.getChar(i1);
c2 = chunk2.getChar(i2);
}
if (c1 == c2)
return 0;
else if (c1 == 0)
return -1;
else
return 1;
}
public static int stringCompare(Database db, int record1, char[] record2) throws CoreException {
Chunk chunk1 = db.getChunk(record1);
int i1 = record1;
int i2 = 0;
char c1 = chunk1.getChar(i1);
char c2 = i2 < record2.length ? record2[i2] : 0;
while (c1 != 0 && c2 != 0) {
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
i1 += 2;
++i2;
c1 = chunk1.getChar(i1);
c2 = i2 < record2.length ? record2[i2] : 0;
}
if (c1 == c2)
return 0;
else if (c1 == 0)
return -1;
else
return 1;
}
public static int stringCompare(Database db, int record1, String record2) throws CoreException {
Chunk chunk1 = db.getChunk(record1);
int i1 = record1;
int i2 = 0;
int n2 = record2.length();
char c1 = chunk1.getChar(i1);
char c2 = i2 < n2 ? record2.charAt(i2) : 0;
while (c1 != 0 && c2 != 0) {
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
i1 += 2;
++i2;
c1 = chunk1.getChar(i1);
c2 = i2 < n2 ? record2.charAt(i2) : 0;
}
if (c1 == c2)
return 0;
else if (c1 == 0)
return -1;
else
return 1;
}
}

View file

@ -243,6 +243,9 @@ public class BTree {
}
}
if (!found)
return visit(getChild(chunk, node, i), visitor, false);
return true;
}

View file

@ -56,33 +56,30 @@ public class Chunk {
return buffer.getChar(offset % Database.CHUNK_SIZE);
}
// Strings have a 16 bit length followed by the chars
public void putChars(int offset, char[] value) {
buffer.position(offset % Database.CHUNK_SIZE);
buffer.putChar((char)value.length);
for (int i = 0; i < value.length; ++i)
buffer.putChar(value[i]);
buffer.putChar((char)0);
}
public char[] getChars(int offset) {
buffer.position(offset % Database.CHUNK_SIZE);
int n = 0;
for (char c = buffer.getChar(); c != 0; c = buffer.getChar())
++n;
buffer.position(offset % Database.CHUNK_SIZE);
int n = buffer.getChar();
char[] chars = new char[n];
int i = 0;
for (char c = buffer.getChar(); c != 0; c = buffer.getChar())
chars[i++] = c;
for (int i = 0; i < n; ++i)
chars[i] = buffer.getChar();
return chars;
}
public void putString(int offset, String value) {
buffer.position(offset % Database.CHUNK_SIZE);
int n = value.length();
buffer.putChar((char)n);
for (int i = 0; i < n; ++i)
buffer.putChar(value.charAt(i));
buffer.putChar((char)0);
}
public String getString(int offset) {

View file

@ -279,4 +279,93 @@ public class Database {
public int getNumChunks() {
return toc.length;
}
public int stringCompare(int record1, int record2) throws CoreException {
Chunk chunk1 = getChunk(record1);
Chunk chunk2 = getChunk(record2);
int i1 = record1 + 2;
int i2 = record2 + 2;
int n1 = i1 + chunk1.getChar(record1) * 2;
int n2 = i2 + chunk2.getChar(record2) * 2;
while (i1 < n1 && i2 < n2) {
char c1 = chunk1.getChar(i1);
char c2 = chunk2.getChar(i2);
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
i1 += 2;
i2 += 2;
}
if (i1 == n1 && i2 != n2)
return -1;
else if (i2 == n2 && i1 != n1)
return 1;
else
return 0;
}
public int stringCompare(int record1, char[] record2) throws CoreException {
Chunk chunk1 = getChunk(record1);
int i1 = record1 + 2;
int i2 = 0;
int n1 = i1 + chunk1.getChar(record1) * 2;
int n2 = record2.length;
while (i1 < n1 && i2 < n2) {
char c1 = chunk1.getChar(i1);
char c2 = record2[i2];
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
i1 += 2;
++i2;
}
if (i1 == n1 && i2 != n2)
return -1;
else if (i2 == n2 && i1 != n1)
return 1;
else
return 0;
}
public int stringCompare(int record1, String record2) throws CoreException {
Chunk chunk1 = getChunk(record1);
int i1 = record1 + 2;
int i2 = 0;
int n1 = i1 + chunk1.getChar(record1) * 2;
int n2 = record2.length();
while (i1 < n1 && i2 < n2) {
char c1 = chunk1.getChar(i1);
char c2 = record2.charAt(i2);
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
i1 += 2;
++i2;
}
if (i1 == n1 && i2 != n2)
return -1;
else if (i2 == n2 && i1 != n1)
return 1;
else
return 0;
}
}

View file

@ -1,58 +0,0 @@
/*******************************************************************************
* Copyright (c) 2005 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db;
import org.eclipse.core.runtime.CoreException;
/**
* @author Doug Schaefer
*
*/
public class StringComparator implements IBTreeComparator {
protected Database db;
protected int offset;
public StringComparator(Database db, int offset) {
this.db = db;
this.offset = offset;
}
public int compare(int record1, int record2) throws CoreException {
Chunk chunk1 = db.getChunk(record1);
Chunk chunk2 = db.getChunk(record2);
int i1 = record1 + offset;
int i2 = record2 + offset;
char c1 = chunk1.getChar(i1);
char c2 = chunk2.getChar(i2);
while (c1 != 0 && c2 != 0) {
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
i1 += 2;
i2 += 2;
c1 = chunk1.getChar(i1);
c2 = chunk2.getChar(i2);
}
if (c1 == c2)
return 0;
else if (c1 == 0)
return -1;
else
return 1;
}
}

View file

@ -1,59 +0,0 @@
/*******************************************************************************
* Copyright (c) 2005 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db;
import org.eclipse.core.runtime.CoreException;
/**
* @author Doug Schaefer
*
*/
public abstract class StringVisitor implements IBTreeVisitor {
public final Database db;
private final int offset;
private final String key;
public StringVisitor(Database db, int offset, String key) {
this.db = db;
this.offset = offset;
this.key = key;
}
public int compare(int record) throws CoreException {
Chunk chunk = db.getChunk(record);
int i1 = record + offset;
int i2 = 0;
int n2 = key.length();
char c1 = chunk.getChar(i1);
char c2 = i2 < n2 ? key.charAt(i2) : 0;
while (c1 != 0 && c2 != 0) {
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
i1 += 2;
i2 += 1;
c1 = chunk.getChar(i1);
c2 = i2 < n2 ? key.charAt(i2) : 0;
}
if (c1 == c2)
return 0;
else if (c1 == 0)
return -1;
else
return 1;
}
}

View file

@ -17,7 +17,6 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.internal.core.pdom.PDOMDatabase;
import org.eclipse.cdt.internal.core.pdom.PDOMUtils;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
@ -57,7 +56,7 @@ public class PDOMBinding implements IBinding {
int string2 = db.getInt(record2 + STRING_REC_OFFSET);
// Need to deal with language and type
return PDOMUtils.stringCompare(db, string1, string2);
return db.stringCompare(string1, string2);
}
}
@ -76,7 +75,7 @@ public class PDOMBinding implements IBinding {
int string1 = db.getInt(record1 + STRING_REC_OFFSET);
// Need to deal with language and type
return PDOMUtils.stringCompare(db, string1, key);
return db.stringCompare(string1, key);
}
}
@ -153,7 +152,7 @@ public class PDOMBinding implements IBinding {
firstDeclaration.setPrevInBinding(name);
name.setNextInBinding(firstDeclaration);
}
pdom.getDB().putInt(record + FIRST_DECL_OFFSET, name.getRecord());
setFirstDeclaration(name);
}
public PDOMName getFirstDeclaration() throws CoreException {

View file

@ -13,8 +13,8 @@ package org.eclipse.cdt.internal.core.pdom.dom;
import org.eclipse.cdt.internal.core.pdom.PDOMDatabase;
import org.eclipse.cdt.internal.core.pdom.db.BTree;
import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.db.StringComparator;
import org.eclipse.cdt.internal.core.pdom.db.StringVisitor;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
import org.eclipse.core.runtime.CoreException;
/**
@ -31,17 +31,29 @@ public class PDOMFile {
private static final int FIRST_NAME_OFFSET = 0;
private static final int FILE_NAME_OFFSET = Database.INT_SIZE;
public static class Comparator extends StringComparator {
public static class Comparator implements IBTreeComparator {
private Database db;
public Comparator(Database db) {
super(db, FILE_NAME_OFFSET);
this.db = db;
}
public int compare(int record1, int record2) throws CoreException {
return db.stringCompare(record1 + FILE_NAME_OFFSET, record2 + FILE_NAME_OFFSET);
}
}
public abstract static class Visitor extends StringVisitor {
public abstract static class Visitor implements IBTreeVisitor {
private Database db;
private String key;
public Visitor(Database db, String key) {
super(db, FILE_NAME_OFFSET, key);
this.db = db;
this.key = key;
}
public int compare(int record) throws CoreException {
return db.stringCompare(record + FILE_NAME_OFFSET, key);
}
}