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:
parent
438433b2fd
commit
0324c8d8de
10 changed files with 138 additions and 249 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -243,6 +243,9 @@ public class BTree {
|
|||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return visit(getChild(chunk, node, i), visitor, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue