mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-30 04:15:35 +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:
|
* Contributors:
|
||||||
* QNX - Initial API and implementation
|
* QNX - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* IBM Corporation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom;
|
package org.eclipse.cdt.internal.core.pdom;
|
||||||
|
|
||||||
|
@ -174,7 +175,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
|
||||||
protected void clear() throws CoreException {
|
protected void clear() throws CoreException {
|
||||||
Database db = getDB();
|
Database db = getDB();
|
||||||
// Clear out the database
|
// Clear out the database
|
||||||
db.clear();
|
db.clear(0);
|
||||||
|
|
||||||
// Zero out the File Index and Linkages
|
// Zero out the File Index and Linkages
|
||||||
db.putInt(FILE_INDEX, 0);
|
db.putInt(FILE_INDEX, 0);
|
||||||
|
|
|
@ -8,13 +8,17 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX - Initial API and implementation
|
* QNX - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* IBM Corporation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom.db;
|
package org.eclipse.cdt.internal.core.pdom.db;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.nio.MappedByteBuffer;
|
import java.nio.MappedByteBuffer;
|
||||||
import java.nio.channels.FileChannel.MapMode;
|
import java.nio.channels.FileChannel.MapMode;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
|
@ -101,8 +105,21 @@ public class Chunk {
|
||||||
buffer.put(new byte[length]);
|
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
|
* QNX - Initial API and implementation
|
||||||
* Symbian - Add some non-javadoc implementation notes
|
* Symbian - Add some non-javadoc implementation notes
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* IBM Corporation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.pdom.db;
|
package org.eclipse.cdt.internal.core.pdom.db;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
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.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
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
|
* Empty the contents of the Database, make it ready to start again
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
public void clear() throws CoreException {
|
public void clear(long timeout) throws CoreException {
|
||||||
// Clear out the memory headers
|
// Clear out the memory headers
|
||||||
toc[0].clear(4, DATA_AREA - 4);
|
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) {
|
if (!truncate(timeout)) {
|
||||||
addBlock(getChunk(block), CHUNK_SIZE, block);
|
// 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;
|
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.
|
* Return the Chunk that contains the given offset.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Reference in a new issue