diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 81f3e4a23b7..e91741d33b3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -165,9 +165,14 @@ public class PDOM extends PlatformObject public void clear() throws CoreException { Database db = getDB(); + // Clear out the database db.clear(); - db.setVersion(VERSION); + + // Zero out the File Index and Linkages + db.putInt(FILE_INDEX, 0); fileIndex = null; + + db.putInt(LINKAGES, 0); linkageCache.clear(); } 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 efdfafcb0b0..3782cb691eb 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 @@ -173,7 +173,7 @@ public class BTree { } private int allocateNode() throws CoreException { - return db.malloc((2 * NUM_RECORDS - 1) * Database.INT_SIZE); + return db.malloc((2 * NUM_RECORDS + 1) * Database.INT_SIZE); } /** 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 9b0b1d3c9b9..b2aa55a4b0d 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 @@ -27,6 +27,9 @@ public class Database { private final RandomAccessFile file; Chunk[] toc; + private long malloced; + private long freed; + // public for tests only, you shouldn't need these public static final int VERSION_OFFSET = 0; public static final int CHUNK_SIZE = 1024 * 16; @@ -46,31 +49,18 @@ public class Database { // Allocate chunk table, make sure we have at least one long nChunks = file.length() / CHUNK_SIZE; if (nChunks == 0) { - create(); + file.seek(0); + file.write(new byte[CHUNK_SIZE]); // the header chunk ++nChunks; } toc = new Chunk[(int)nChunks]; - init(); + toc[0] = new Chunk(file, 0); } catch (IOException e) { throw new CoreException(new DBStatus(e)); } } - private void create() throws CoreException { - try { - file.seek(0); - file.write(new byte[CHUNK_SIZE]); // the header chunk - } catch (IOException e) { - throw new CoreException(new DBStatus(e)); - } - } - - private void init() throws CoreException { - // Load in the magic chunk zero - toc[0] = new Chunk(file, 0); - } - public int getVersion() { return toc[0].getInt(0); } @@ -84,11 +74,13 @@ public class Database { * @throws CoreException */ public void clear() throws CoreException { - int version = toc[0].getInt(0); - create(); - toc = new Chunk[1]; - init(); - setVersion(version); + // Clear out the memory headers + toc[0].clear(4, DATA_AREA - 4); + // Add the remainder of the chunks backwards + for (int block = (toc.length - 1) * CHUNK_SIZE; block > 0; block -= CHUNK_SIZE) { + addBlock(getChunk(block), CHUNK_SIZE, block); + } + malloced = freed = 0; } /** @@ -153,8 +145,12 @@ public class Database { // Make our size negative to show in use chunk.putInt(freeblock, - matchsize); - - return freeblock + INT_SIZE; + + // Clear out the block, lots of people are expecting this + chunk.clear(freeblock + 4, size); + + malloced += matchsize; + return freeblock + 4; } private int createChunk() throws CoreException { @@ -219,8 +215,8 @@ public class Database { if (blocksize < 0) // already freed throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, 0, "Already Freed", new Exception())); - chunk.clear(offset, blocksize - 4); addBlock(chunk, blocksize, block); + freed += blocksize; } public void putByte(int offset, byte value) throws CoreException { @@ -279,4 +275,21 @@ public class Database { return toc.length; } + public void reportFreeBlocks() throws CoreException { + System.out.println("Allocated size: " + toc.length * CHUNK_SIZE); + System.out.println("malloc'ed: " + malloced); + System.out.println("free'd: " + freed); + System.out.println("wasted: " + (toc.length * CHUNK_SIZE - (malloced - freed))); + System.out.println("Free blocks"); + for (int bs = MIN_SIZE; bs <= CHUNK_SIZE; bs += MIN_SIZE) { + int count = 0; + int block = getFirstBlock(bs); + while (block != 0) { + ++count; + block = getInt(block + NEXT_OFFSET); + } + if (count != 0) + System.out.println("Block size: " + bs + "=" + count); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IString.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IString.java index c0d5eab0759..f799766b37a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IString.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IString.java @@ -32,4 +32,5 @@ public interface IString { public char[] getChars() throws CoreException; public String getString() throws CoreException; + public void delete() throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/LongString.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/LongString.java index 351686e9b25..83639841960 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/LongString.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/LongString.java @@ -103,6 +103,23 @@ public class LongString implements IString { return record1; } + public void delete() throws CoreException { + int length = db.getInt(record1 + LENGTH) - NUM_CHARS1; + int nextRecord = db.getInt(record1 + NEXT1); + db.free(record1); + + // Middle records + while (length > NUM_CHARSN) { + length -= NUM_CHARSN; + int nextnext = db.getInt(nextRecord + NEXTN); + db.free(nextRecord); + nextRecord = nextnext; + } + + // Last record + db.free(nextRecord); + } + public boolean equals(Object obj) { throw new PDOMNotImplementedError(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ShortString.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ShortString.java index 609c87dea58..5db3afcf76d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ShortString.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/ShortString.java @@ -53,7 +53,7 @@ public class ShortString implements IString { this.record = db.malloc(CHARS + string.length() * 2); Chunk chunk = db.getChunk(record); - chunk.putInt(record + LENGTH, (char)string.length()); + chunk.putInt(record + LENGTH, string.length()); int n = string.length(); int p = record + CHARS; for (int i = 0; i < n; ++i) { @@ -66,6 +66,10 @@ public class ShortString implements IString { return record; } + public void delete() throws CoreException { + db.free(record); + } + public char[] getChars() throws CoreException { Chunk chunk = db.getChunk(record); int length = chunk.getInt(record + LENGTH); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java index 1b8568870b3..be2f2c54891 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java @@ -77,6 +77,11 @@ public class PDOMMacro { } public void delete() throws CoreException { + getName().delete(); + getExpansion().delete(); + PDOMMacroParameter param = getFirstParameter(); + if (param != null) + param.delete(); pdom.getDB().free(record); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroParameter.java index be11d3396c8..fd2df21eb6a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacroParameter.java @@ -49,6 +49,14 @@ public class PDOMMacroParameter { return record; } + public void delete() throws CoreException { + PDOMMacroParameter next = getNextParameter(); + if (next != null) + next.delete(); + getName().delete(); + pdom.getDB().free(record); + } + public void setNextParameter(PDOMMacroParameter next) throws CoreException { int rec = next != null ? next.getRecord() : 0; pdom.getDB().putInt(record + NEXT, rec); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java index 30db548f342..f445f39b339 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java @@ -63,6 +63,7 @@ public class CountNodeAction extends IndexAction { ICProject project = (ICProject)objs[i]; final PDOM pdom = (PDOM)CCorePlugin.getPDOMManager().getPDOM(project); + //pdom.getDB().reportFreeBlocks(); pdom.getFileIndex().accept(new IBTreeVisitor() { public int compare(int record) throws CoreException {