blob: dc9bee5781968c75cfb3120419692d538665cc43 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2013 SAP AG and IBM Corporation.
* 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:
* SAP AG - initial API and implementation
* IBM Corporation - multiple heap dumps
*******************************************************************************/
package org.eclipse.mat.hprof;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.collect.IteratorLong;
import org.eclipse.mat.hprof.extension.IParsingEnhancer;
import org.eclipse.mat.hprof.ui.HprofPreferences;
import org.eclipse.mat.parser.IIndexBuilder;
import org.eclipse.mat.parser.IPreliminaryIndex;
import org.eclipse.mat.parser.index.IIndexReader.IOne2LongIndex;
import org.eclipse.mat.parser.index.IndexWriter;
import org.eclipse.mat.util.IProgressListener;
import org.eclipse.mat.util.MessageUtil;
import org.eclipse.mat.util.SimpleMonitor;
public class HprofIndexBuilder implements IIndexBuilder
{
private File file;
private String prefix;
private IOne2LongIndex id2position;
private List<IParsingEnhancer> enhancers;
public void init(File file, String prefix)
{
this.file = file;
this.prefix = prefix;
this.enhancers = new ArrayList<IParsingEnhancer>();
for (EnhancerRegistry.Enhancer enhancer : EnhancerRegistry.instance().delegates())
{
IParsingEnhancer parsingEnhancer = enhancer.parser();
if (parsingEnhancer != null)
this.enhancers.add(parsingEnhancer);
}
}
public void fill(IPreliminaryIndex preliminary, IProgressListener listener) throws SnapshotException, IOException
{
HprofPreferences.HprofStrictness strictnessPreference = HprofPreferences.getCurrentStrictness();
SimpleMonitor monitor = new SimpleMonitor(MessageUtil.format(Messages.HprofIndexBuilder_Parsing,
new Object[] { file.getAbsolutePath() }), listener, new int[] { 500, 1500 });
listener.beginTask(MessageUtil.format(Messages.HprofIndexBuilder_Parsing, file.getName()), 3000);
IHprofParserHandler handler = new HprofParserHandlerImpl();
handler.beforePass1(preliminary.getSnapshotInfo());
SimpleMonitor.Listener mon = (SimpleMonitor.Listener) monitor.nextMonitor();
mon.beginTask(MessageUtil.format(Messages.HprofIndexBuilder_Scanning, new Object[] { file.getAbsolutePath() }),
(int) (file.length() / 1000));
Pass1Parser pass1 = new Pass1Parser(handler, mon, strictnessPreference);
Serializable id = preliminary.getSnapshotInfo().getProperty("$runtimeId"); //$NON-NLS-1$
String dumpNrToRead;
if (id instanceof String)
{
dumpNrToRead = (String)id;
}
else
{
dumpNrToRead = pass1.determineDumpNumber();
}
pass1.read(file, dumpNrToRead);
if (listener.isCanceled())
throw new IProgressListener.OperationCanceledException();
mon.done();
handler.beforePass2(listener);
mon = (SimpleMonitor.Listener) monitor.nextMonitor();
mon.beginTask(MessageUtil.format(Messages.HprofIndexBuilder_ExtractingObjects,
new Object[] { file.getAbsolutePath() }), (int) (file.length() / 1000));
Pass2Parser pass2 = new Pass2Parser(handler, mon, strictnessPreference);
pass2.read(file, dumpNrToRead);
if (listener.isCanceled())
throw new IProgressListener.OperationCanceledException();
mon.done();
if (listener.isCanceled())
throw new IProgressListener.OperationCanceledException();
for (IParsingEnhancer enhancer : enhancers)
enhancer.onParsingCompleted(handler.getSnapshotInfo());
id2position = handler.fillIn(preliminary);
}
public void clean(final int[] purgedMapping, IProgressListener listener) throws IOException
{
// //////////////////////////////////////////////////////////////
// object 2 hprof position
// //////////////////////////////////////////////////////////////
File indexFile = new File(prefix + "o2hprof.index"); //$NON-NLS-1$
listener.subTask(MessageUtil.format(Messages.HprofIndexBuilder_Writing,
new Object[] { indexFile.getAbsolutePath() }));
IOne2LongIndex newIndex = new IndexWriter.LongIndexStreamer().writeTo(indexFile, new IndexIterator(id2position,
purgedMapping));
try
{
newIndex.close();
}
catch (IOException ignore)
{}
try
{
id2position.close();
}
catch (IOException ignore)
{}
id2position.delete();
id2position = null;
}
public void cancel()
{
if (id2position != null)
{
try
{
id2position.close();
}
catch (IOException ignore)
{
// $JL-EXC$
}
id2position.delete();
}
}
private static final class IndexIterator implements IteratorLong
{
private final IOne2LongIndex id2position;
private final int[] purgedMapping;
private int nextIndex = -1;
private IndexIterator(IOne2LongIndex id2position, int[] purgedMapping)
{
this.id2position = id2position;
this.purgedMapping = purgedMapping;
findNext();
}
public boolean hasNext()
{
return nextIndex < purgedMapping.length;
}
public long next()
{
long answer = id2position.get(nextIndex);
findNext();
return answer;
}
protected void findNext()
{
nextIndex++;
while (nextIndex < purgedMapping.length && purgedMapping[nextIndex] < 0)
nextIndex++;
}
}
}