
org.neo4j.helpers.ProgressIndicator Maven / Gradle / Ivy
/**
* Copyright (c) 2002-2013 "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 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.helpers;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
/**
* A generic interface for reporting progress by a tool. Can be implemented to
* support reporting progress from both a {@link SimpleProgress single source},
* or for the aggregate of {@link MultiProgress multiple sources}.
*
* @deprecated use {@link Progress} instead.
*
* @author Tobias Lindaaker
*/
@Deprecated
public interface ProgressIndicator
{
/**
* Update the current progress count for the current source.
*
* @param incremental whether this is an incremental update (
* true
) or an absolute assignment (
* false
) of the progress.
* @param value the count to update the progress with.
*/
void update( boolean incremental, long value );
/**
* Mark the process as done with the current source.
*
* @param totalProgress the total progress reached by the source.
*/
void done( long totalProgress );
/**
* A {@link ProgressIndicator} that can report the progress for a single
* source.
*
* Should be initialized with the total count that the source is going to
* reach.
*
* @author Tobias Lindaaker
*/
public abstract class SimpleProgress implements ProgressIndicator
{
private final long total;
private int lastPermille = 0;
private long currentProgress = 0;
/**
* Create a {@link ProgressIndicator} for a single source.
*
* @param total the total count the process will reach.
*/
public SimpleProgress( long total )
{
this.total = total;
}
/**
* Returns a simple {@link ProgressIndicator} that reports progress by
* printing to the provided stream.
*
* @param out the stream to print progress indication to.
* @param total the total count the process will reach.
* @return a simple {@link ProgressIndicator} that reports progress by
* printing to the provided stream.
*/
public static SimpleProgress textual( final PrintStream out, long total )
{
return new SimpleProgress( total )
{
@Override
protected void progress( int permille )
{
textualProgress( out, permille );
}
};
}
long currentProgress( boolean incremental, long value )
{
return currentProgress = ( incremental ? ( currentProgress + value ) : value );
}
@Override
public void update( boolean incremental, long value )
{
int permille = (int) ( ( currentProgress( incremental, value ) * 1000 ) / total );
if ( permille != lastPermille ) progress( lastPermille = permille );
}
@Override
public void done( long totalProgress )
{
done();
}
void done()
{
if ( lastPermille < 1000 ) progress( lastPermille = 1000 );
}
/**
* Implement this method to emit the progress notifications.
*
* @param permille value from 0 (just started) to 1000 (done) indicating
* how far along the process is.
*/
protected abstract void progress( int permille );
static void textualProgress( PrintStream out, int permille )
{
if ( permille % 100 == 0 )
out.printf( "%3s%%%n", Integer.toString( permille / 10 ) );
else if ( permille % 5 == 0 ) out.print( "." );
}
}
/**
* A {@link ProgressIndicator} that can report the total progress for
* multiple sources.
*
* Needs to be initialized with the total count that should be reached by
* all sources together.
*
* When the entire process (all sources) is completed, {@link #done()} needs
* to be invoked.
*
* @author Tobias Lindaaker
*/
public abstract class MultiProgress extends SimpleProgress
{
private long base = 0;
/**
* Create a {@link ProgressIndicator} for multiple sources.
*
* @param total the total count the entire process (all sources) will
* reach.
*/
public MultiProgress( long total )
{
super( total );
}
/**
* Returns a simple {@link ProgressIndicator} that reports progress by
* printing to the provided stream.
*
* @param out the stream to print progress indication to.
* @param total the total count the entire process (all sources) will
* reach.
* @return a simple {@link ProgressIndicator} that reports progress by
* printing to the provided stream.
*/
public static MultiProgress textual( final PrintStream out, long total )
{
return new MultiProgress( total )
{
@Override
protected void progress( int permille )
{
textualProgress( out, permille );
}
};
}
@Override
long currentProgress( boolean incremental, long value )
{
return base + super.currentProgress( incremental, value );
}
@Override
public void done( long totalSegmentProgress )
{
update( false, totalSegmentProgress );
base += totalSegmentProgress;
currentProgress( false, 0 ); // reset for the next count
}
/**
* Signal that the entire progress (all sources) is done.
*/
@Override
public void done()
{
super.done();
}
}
/**
* Progress indicator where the end is unknown. Specify a step size which
* means that a means of progress will be printed every step.
*
* @author Mattias Persson
*/
public class UnknownEndProgress implements ProgressIndicator
{
private final long stepSize;
private long lastAbsolutePosition = -1;
private long position;
private long lastStep;
private final String doneMessage;
private final PrintStream out;
public UnknownEndProgress( long stepSize, String doneMessage )
{
try {
this.stepSize = stepSize;
this.doneMessage = doneMessage;
this.out = new PrintStream(System.out, /* auto-flush=*/false, "utf-8" );
} catch(UnsupportedEncodingException e)
{
throw new RuntimeException("Your platform does not support utf-8 encoded strings, " +
"which is required for this library to work.", e);
}
}
public UnknownEndProgress(long stepSize, String doneMessage, PrintStream out)
{
this.stepSize = stepSize;
this.doneMessage = doneMessage;
this.out = out;
}
@Override
public void update( boolean incremental, long value )
{
position += incremental ? updateIncremental( value ) : updateAbsolute( value );
long step = position/stepSize;
if ( lastStep != step )
{
if ( lastStep > 0 && lastStep % 30 == 0 ) out.println();
out.print( "." );
}
lastStep = step;
}
private long updateIncremental( long value )
{
return value;
}
private long updateAbsolute( long value )
{
if ( lastAbsolutePosition == -1 ) lastAbsolutePosition = value;
try
{
return value - lastAbsolutePosition;
}
finally
{
lastAbsolutePosition = value;
}
}
@Override
public void done( long totalProgress )
{
if ( lastStep > 0 ) out.println();
out.println( "[" + totalProgress + " " + doneMessage + "]" );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy