package com.ldbc.driver;
import com.ldbc.driver.control.DriverConfiguration;
import com.ldbc.driver.generator.GeneratorFactory;
import com.ldbc.driver.validation.ResultsLogValidationTolerances;
import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public abstract class Workload implements Closeable
{
public static final long DEFAULT_MAXIMUM_EXPECTED_INTERLEAVE_AS_MILLI = TimeUnit.HOURS.toMillis( 1 );
private boolean isInitialized = false;
private boolean isClosed = false;
public abstract Map<Integer,Class<? extends Operation>> operationTypeToClassMapping();
public ResultsLogValidationTolerances resultsLogValidationTolerances(
DriverConfiguration configuration,
boolean warmup
)
{
long excessiveDelayThresholdAsMilli = TimeUnit.SECONDS.toMillis( 1 );
double toleratedExcessiveDelayCountPercentage = 0.01;
long toleratedExcessiveDelayCount =
(warmup) ? Math.round( configuration.warmupCount() * toleratedExcessiveDelayCountPercentage )
: Math.round( configuration.operationCount() * toleratedExcessiveDelayCountPercentage );
// TODO this should really be percentages instead of absolute numbers
Map<String,Long> toleratedExcessiveDelayCountPerType = new HashMap<>();
for ( Class operationType : operationTypeToClassMapping().values() )
{
toleratedExcessiveDelayCountPerType.put( operationType.getSimpleName(), 10l );
}
return new ResultsLogValidationTolerances(
excessiveDelayThresholdAsMilli,
toleratedExcessiveDelayCount,
toleratedExcessiveDelayCountPerType
);
}
/**
* Called once to initialize state for workload
*/
public final void init( DriverConfiguration params ) throws WorkloadException
{
if ( isInitialized )
{ throw new WorkloadException( "Workload may be initialized only once" ); }
isInitialized = true;
onInit( params.asMap() );
}
public abstract void onInit( Map<String,String> params ) throws WorkloadException;
public final void close() throws IOException
{
if ( isClosed )
{
throw new IOException( "Workload may be cleaned up only once" );
}
isClosed = true;
onClose();
}
protected abstract void onClose() throws IOException;
public final WorkloadStreams streams( GeneratorFactory gf, boolean hasDbConnected ) throws WorkloadException
{
if ( false == isInitialized )
{ throw new WorkloadException( "Workload has not been initialized" ); }
return getStreams( gf, hasDbConnected );
}
protected abstract WorkloadStreams getStreams( GeneratorFactory generators, boolean hasDbConnected )
throws WorkloadException;
public DbValidationParametersFilter dbValidationParametersFilter( final Integer requiredValidationParameterCount )
{
return new DbValidationParametersFilter()
{
private final List<Operation> injectedOperations = new ArrayList<>();
int validationParameterCount = 0;
@Override
public boolean useOperation( Operation operation )
{
return true;
}
@Override
public DbValidationParametersFilterResult useOperationAndResultForValidation(
Operation operation,
Object operationResult )
{
if ( validationParameterCount < requiredValidationParameterCount )
{
validationParameterCount++;
return new DbValidationParametersFilterResult(
DbValidationParametersFilterAcceptance.ACCEPT_AND_CONTINUE,
injectedOperations
);
}
else
{
return new DbValidationParametersFilterResult(
DbValidationParametersFilterAcceptance.REJECT_AND_FINISH,
injectedOperations
);
}
}
};
}
public long maxExpectedInterleaveAsMilli()
{
return DEFAULT_MAXIMUM_EXPECTED_INTERLEAVE_AS_MILLI;
}
public abstract String serializeOperation( Operation operation ) throws SerializingMarshallingException;
public abstract Operation marshalOperation( String serializedOperation ) throws SerializingMarshallingException;
public abstract boolean resultsEqual( Operation operation, Object result1, Object result2 )
throws WorkloadException;
public interface DbValidationParametersFilter
{
boolean useOperation( Operation operation );
DbValidationParametersFilterResult useOperationAndResultForValidation(
Operation operation,
Object operationResult );
}
public enum DbValidationParametersFilterAcceptance
{
ACCEPT_AND_CONTINUE,
ACCEPT_AND_FINISH,
REJECT_AND_CONTINUE,
REJECT_AND_FINISH;
}
public static class DbValidationParametersFilterResult
{
private final DbValidationParametersFilterAcceptance acceptance;
private final List<Operation> injectedOperations;
public DbValidationParametersFilterResult(
DbValidationParametersFilterAcceptance acceptance,
List<Operation> injectedOperations )
{
this.acceptance = acceptance;
this.injectedOperations = injectedOperations;
}
public DbValidationParametersFilterAcceptance acceptance()
{
return acceptance;
}
public List<Operation> injectedOperations()
{
return injectedOperations;
}
}
}