1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 145415 - Made sure we deleted all the info associated with the macro, not just the macro. Also found latent bugs like BTree records not allocating enough memory for themselves (hidden by the block size), and goofy behavior when the PDOM was cleared which I'm sure lead to the truncated chunks not getting reused in certain situations.

This commit is contained in:
Doug Schaefer 2006-06-09 00:59:42 +00:00
parent 21f564232c
commit 2372381692
9 changed files with 81 additions and 27 deletions

View file

@ -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();
}

View file

@ -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);
}
/**

View file

@ -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);
}
}
}

View file

@ -32,4 +32,5 @@ public interface IString {
public char[] getChars() throws CoreException;
public String getString() throws CoreException;
public void delete() throws CoreException;
}

View file

@ -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();
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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 {