From 0324c8d8def4cae719c03fd96ae423f9c39b593e Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Fri, 2 Dec 2005 20:00:51 +0000 Subject: [PATCH] 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. --- .../cdt/internal/pdom/tests/DBTest.java | 24 ++-- .../cdt/internal/core/pdom/PDOMLanguage.java | 2 +- .../cdt/internal/core/pdom/PDOMUtils.java | 104 ------------------ .../cdt/internal/core/pdom/db/BTree.java | 3 + .../cdt/internal/core/pdom/db/Chunk.java | 17 ++- .../cdt/internal/core/pdom/db/Database.java | 89 +++++++++++++++ .../core/pdom/db/StringComparator.java | 58 ---------- .../internal/core/pdom/db/StringVisitor.java | 59 ---------- .../internal/core/pdom/dom/PDOMBinding.java | 7 +- .../cdt/internal/core/pdom/dom/PDOMFile.java | 24 +++- 10 files changed, 138 insertions(+), 249 deletions(-) delete mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUtils.java delete mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringComparator.java delete mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringVisitor.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java index e275269a850..95c037c3bdf 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMLanguage.java index d3035e07863..c0ff252016d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMLanguage.java @@ -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; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUtils.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUtils.java deleted file mode 100644 index a1d5a06ee74..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUtils.java +++ /dev/null @@ -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; - - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java index 025057a3d2a..04af1aef021 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java @@ -243,6 +243,9 @@ public class BTree { } } + if (!found) + return visit(getChild(chunk, node, i), visitor, false); + return true; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java index 1fb56ac5f9d..4833eefb5b5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java index f4207bd4fa7..386c34c047a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java @@ -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; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringComparator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringComparator.java deleted file mode 100644 index 42d4e02b3b5..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringComparator.java +++ /dev/null @@ -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; - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringVisitor.java deleted file mode 100644 index 312c4dbdd96..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringVisitor.java +++ /dev/null @@ -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; - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java index 01f0178169a..8a2b30b2af1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java @@ -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 { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java index 05643f80cb2..22f11bbbb06 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMFile.java @@ -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); } }