package com.ldbc.driver.validation;
import com.ldbc.driver.csv.simple.SimpleCsvFileReader;
import com.ldbc.driver.temporal.TemporalUtil;
import java.io.File;
import java.io.FileNotFoundException;
import static com.ldbc.driver.validation.ResultsLogValidationResult.ValidationErrorType;
import static java.lang.String.format;
public class ResultsLogValidator
{
private static final TemporalUtil TEMPORAL_UTIL = new TemporalUtil();
public ResultsLogValidationResult validate(
ResultsLogValidationSummary summary,
ResultsLogValidationTolerances tolerances )
{
ResultsLogValidationResult result = new ResultsLogValidationResult();
if ( summary.excessiveDelayCount() > tolerances.toleratedExcessiveDelayCount() )
{
result.addError(
ValidationErrorType.TOO_MANY_LATE_OPERATIONS,
format( "Late Count (%s) > (%s) Tolerated Late Count",
summary.excessiveDelayCount(),
tolerances.toleratedExcessiveDelayCount() )
);
}
for ( String operationType : summary.excessiveDelayCountPerType().keySet() )
{
long excessiveDelayCountForOperationType = summary.excessiveDelayCountPerType().get( operationType );
if ( tolerances.toleratedExcessiveDelayCountPerType().containsKey( operationType ) &&
tolerances.toleratedExcessiveDelayCountPerType().get( operationType ) <
excessiveDelayCountForOperationType )
{
result.addError(
ValidationErrorType.TOO_MANY_LATE_OPERATIONS_FOR_TYPE,
format( "Late Count for %s (%s) > (%s) Tolerated Late Count",
operationType,
summary.excessiveDelayCountPerType().get( operationType ),
tolerances.toleratedExcessiveDelayCountPerType().get( operationType ) )
);
}
}
return result;
}
public ResultsLogValidationSummary compute( File resultsLog, long excessiveDelayThresholdAsMilli )
throws ValidationException
{
long maxDelayAsMilli = maxDelayAsMilli( resultsLog );
ResultsLogValidationSummaryCalculator calculator = new ResultsLogValidationSummaryCalculator(
maxDelayAsMilli,
excessiveDelayThresholdAsMilli
);
try ( SimpleCsvFileReader reader = new SimpleCsvFileReader(
resultsLog,
SimpleCsvFileReader.DEFAULT_COLUMN_SEPARATOR_REGEX_STRING ) )
{
// skip headers
reader.next();
while ( reader.hasNext() )
{
String[] row = reader.next();
String operationType = row[0];
long scheduledStartTimeAsMilli = Long.parseLong( row[1] );
long actualStartTimeAsMilli = Long.parseLong( row[2] );
// duration
// result code
long delayAsMilli = actualStartTimeAsMilli - scheduledStartTimeAsMilli;
calculator.recordDelay( operationType, delayAsMilli );
}
}
catch ( FileNotFoundException e )
{
throw new ValidationException( format( "Error opening results log: %s", resultsLog.getAbsolutePath() ), e );
}
return calculator.snapshot();
}
private long maxDelayAsMilli( File resultsLog ) throws ValidationException
{
long maxDelayAsMilli = 0;
try ( SimpleCsvFileReader reader = new SimpleCsvFileReader(
resultsLog,
SimpleCsvFileReader.DEFAULT_COLUMN_SEPARATOR_REGEX_STRING ) )
{
// skip headers
reader.next();
while ( reader.hasNext() )
{
String[] row = reader.next();
// operation type
long scheduledStartTimeAsMilli = Long.parseLong( row[1] );
long actualStartTimeAsMilli = Long.parseLong( row[2] );
// duration
// result code
long delayAsMilli = actualStartTimeAsMilli - scheduledStartTimeAsMilli;
if ( delayAsMilli < 0 )
{
throw new ValidationException(
format( "Delay can not be negative\n" +
"Delay: %s (ms) / %s\n" +
"Scheduled Start Time: %s (ms) / %s\n" +
"Actual Start Time: %s (ms) / %s",
delayAsMilli,
TEMPORAL_UTIL.milliDurationToString( delayAsMilli ),
scheduledStartTimeAsMilli,
TEMPORAL_UTIL.milliTimeToTimeString( scheduledStartTimeAsMilli ),
actualStartTimeAsMilli,
TEMPORAL_UTIL.milliTimeToTimeString( actualStartTimeAsMilli )
)
);
}
if ( delayAsMilli > maxDelayAsMilli )
{
maxDelayAsMilli = delayAsMilli;
}
}
}
catch ( FileNotFoundException e )
{
throw new ValidationException( format( "Error opening results log: %s", resultsLog.getAbsolutePath() ), e );
}
return maxDelayAsMilli;
}
}