mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 14:15:23 +02:00
fix for 164019 by Jason Montojo
This commit is contained in:
parent
cb6c40b03b
commit
da9aa45994
3 changed files with 88 additions and 8 deletions
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* IBM Corporation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
|
@ -174,7 +175,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
|
|||
protected void clear() throws CoreException {
|
||||
Database db = getDB();
|
||||
// Clear out the database
|
||||
db.clear();
|
||||
db.clear(0);
|
||||
|
||||
// Zero out the File Index and Linkages
|
||||
db.putInt(FILE_INDEX, 0);
|
||||
|
|
|
@ -8,13 +8,17 @@
|
|||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* IBM Corporation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
|
@ -101,8 +105,21 @@ public class Chunk {
|
|||
buffer.put(new byte[length]);
|
||||
}
|
||||
|
||||
void free() {
|
||||
db.toc[index] = null;
|
||||
/**
|
||||
* Allow this Chunk to be reclaimed. Objects allocated by thus Chunk
|
||||
* may be registered with a ReferenceQueue to allow for notification
|
||||
* on deallocation. References registered with the queue are added to
|
||||
* the Set references.
|
||||
*
|
||||
* @param queue ReferenceQueue to register allocated objects with, or
|
||||
* null if notification is not required.
|
||||
* @param references Populated with references which were registered
|
||||
* with the queue.
|
||||
*/
|
||||
void reclaim(ReferenceQueue queue, Set references) {
|
||||
if (queue != null) {
|
||||
references.add(new WeakReference(buffer, queue));
|
||||
}
|
||||
buffer = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,12 +9,16 @@
|
|||
* QNX - Initial API and implementation
|
||||
* Symbian - Add some non-javadoc implementation notes
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* IBM Corporation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -106,16 +110,74 @@ public class Database {
|
|||
* Empty the contents of the Database, make it ready to start again
|
||||
* @throws CoreException
|
||||
*/
|
||||
public void clear() throws CoreException {
|
||||
public void clear(long timeout) throws CoreException {
|
||||
// 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);
|
||||
|
||||
if (!truncate(timeout)) {
|
||||
// Truncation timed out so the database size couldn't be changed.
|
||||
// The best we can do is mark all chunks as unallocated blocks.
|
||||
|
||||
// Since the block list grows at the head, add all non-header
|
||||
// chunks backwards to ensure list of blocks is ordered first
|
||||
// to last.
|
||||
for (int block = (toc.length - 1) * CHUNK_SIZE; block > 0; block -= CHUNK_SIZE) {
|
||||
addBlock(getChunk(block), CHUNK_SIZE, block);
|
||||
}
|
||||
}
|
||||
malloced = freed = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate the database as small as possible to reclaim disk space.
|
||||
* This method returns false if truncation does not succeed within the
|
||||
* given timeout period (in milliseconds). A timeout of 0 will cause
|
||||
* this method to block until the database is successfully truncated.
|
||||
*
|
||||
* @param timeout maximum amount of milliseconds to wait before giving up;
|
||||
* 0 means wait indefinitely.
|
||||
* @return true if truncation succeeds; false if the operation times out.
|
||||
* @throws CoreException if an IO error occurs during truncation
|
||||
*/
|
||||
private boolean truncate(long timeout) throws CoreException {
|
||||
// Queue all the chunks to be reclaimed.
|
||||
ReferenceQueue queue = new ReferenceQueue();
|
||||
Set references = new HashSet();
|
||||
for (int i = 0; i < toc.length; i++) {
|
||||
if (toc[i] != null) {
|
||||
toc[i].reclaim(queue, references);
|
||||
toc[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
System.gc();
|
||||
try {
|
||||
// Wait for each chunk to be reclaimed.
|
||||
int totalReclaimed = references.size();
|
||||
while (totalReclaimed > 0) {
|
||||
queue.remove(timeout);
|
||||
totalReclaimed--;
|
||||
}
|
||||
|
||||
// Truncate everything but the header chunk.
|
||||
try {
|
||||
file.getChannel().truncate(CHUNK_SIZE);
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new DBStatus(e));
|
||||
}
|
||||
// Reinitialize header chunk.
|
||||
toc = new Chunk[] { new Chunk(file, 0) };
|
||||
return true;
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
// Truncation took longer than we wanted, so we'll
|
||||
// reinitialize the header chunk and leave the file
|
||||
// size alone.
|
||||
toc[0] = new Chunk(file, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Chunk that contains the given offset.
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue