/**
* Copyright (c) 2002-2012 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.perftest.enterprise.ccheck;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.neo4j.helpers.progress.Indicator;
import org.neo4j.helpers.progress.ProgressMonitorFactory;
public class TimingProgress extends ProgressMonitorFactory
{
public interface Visitor
{
void beginTimingProgress( long totalElementCount, long totalTimeNanos ) throws IOException;
void phaseTimingProgress( String phase, long elementCount, long timeNanos ) throws IOException;
void endTimingProgress() throws IOException;
}
private final Visitor visitor;
private final ProgressMonitorFactory actual;
TimingProgress( Visitor visitor, ProgressMonitorFactory actual )
{
this.visitor = visitor;
this.actual = actual;
}
@Override
protected Indicator newIndicator( String process )
{
return new Indicator.Decorator( actual, process )
{
private final Timer total = new Timer( null );
private long totalCount;
private Map<String, Timer> timers = new HashMap<String, Timer>();
@Override
public void startProcess( long totalCount )
{
super.startProcess( totalCount );
this.totalCount = totalCount;
total.items = totalCount;
total.start();
}
@Override
public void startPart( String part, long totalCount )
{
super.startPart( part, totalCount );
Timer timer = new Timer( part );
timers.put( part, timer );
timer.items = totalCount;
timer.start();
}
@Override
public void completePart( String part )
{
timers.get( part ).stop();
super.completePart( part );
}
@Override
public void completeProcess()
{
total.stop();
super.completeProcess();
this.accept(visitor);
}
private void accept( Visitor visitor )
{
try
{
visitor.beginTimingProgress( total.items, total.time );
for ( Timer timer : timers.values() )
{
timer.accept( visitor );
}
visitor.endTimingProgress();
}
catch ( IOException e )
{
e.printStackTrace();
}
}
};
}
private static class Timer
{
private final String name;
private long time = 0;
private Long start = null;
private long items = 0;
Timer( String name )
{
this.name = name;
}
void complete( long processedItems )
{
stop();
items += processedItems;
}
void start()
{
if ( start == null )
{
start = System.nanoTime();
}
}
void stop()
{
if ( start != null )
{
time += System.nanoTime() - start;
}
start = null;
}
void accept( Visitor visitor ) throws IOException
{
visitor.phaseTimingProgress( name, items, time );
}
}
}