package org.arbeitspferde.groningen;
import com.google.common.collect.Lists;
import com.google.protobuf.InvalidProtocolBufferException;
import org.arbeitspferde.groningen.config.GroningenConfig;
import org.arbeitspferde.groningen.config.ProtoBufConfig;
import org.arbeitspferde.groningen.exceptions.InvalidConfigurationException;
import org.arbeitspferde.groningen.experimentdb.CommandLine;
import org.arbeitspferde.groningen.experimentdb.Experiment;
import org.arbeitspferde.groningen.experimentdb.ExperimentDb;
import org.arbeitspferde.groningen.experimentdb.SubjectStateBridge;
import org.arbeitspferde.groningen.experimentdb.jvmflags.JvmFlag;
import org.arbeitspferde.groningen.experimentdb.jvmflags.JvmFlagSet;
import org.arbeitspferde.groningen.proto.ExperimentDbProtos;
import org.arbeitspferde.groningen.proto.ExperimentDbProtos.Subject;
import org.arbeitspferde.groningen.proto.GroningenConfigProto.ProgramConfiguration;
import java.util.ArrayList;
import java.util.List;
/**
* Object representing PipelineState. Mainly used in {@link Datastore}.
*/
public class PipelineState {
private PipelineId pipelineId;
private GroningenConfig config;
private ExperimentDb experimentDb;
public PipelineState(PipelineId pipelineId, GroningenConfig config, ExperimentDb experimentDb) {
this.pipelineId = pipelineId;
this.config = config;
this.experimentDb = experimentDb;
}
public PipelineState(byte[] bytes) {
org.arbeitspferde.groningen.proto.ExperimentDbProtos.PipelineState stateProto;
try {
stateProto =
org.arbeitspferde.groningen.proto.ExperimentDbProtos.PipelineState.parseFrom(bytes);
} catch (InvalidProtocolBufferException e) {
throw new RuntimeException(e);
}
pipelineId = new PipelineId(stateProto.getId().getId());
try {
config = new ProtoBufConfig(stateProto.getConfiguration());
} catch (InvalidConfigurationException e) {
throw new RuntimeException(e);
}
experimentDb = new ExperimentDb();
final List<Long> subjectIds = Lists.newArrayList();
for (Subject subjectProto : stateProto.getSubjectsList()) {
final SubjectStateBridge bridge = experimentDb.makeSubject(subjectProto.getId());
subjectIds.add(subjectProto.getId());
/* TODO(team): Migrate the stink that this switch statement is into a EnumMap or have
* JvmFlagSet translate the mapping itself.
*/
final JvmFlagSet.Builder builder = JvmFlagSet.builder();
final ExperimentDbProtos.CommandLine cl = subjectProto.getCommandLine();
for (final ExperimentDbProtos.CommandLineArgument arg : cl.getArgumentList()) {
final int value = Integer.parseInt(arg.getValue());
final JvmFlag argument = JvmFlag.valueOf(arg.getName());
switch (argument) {
case ADAPTIVE_SIZE_DECREMENT_SCALE_FACTOR:
builder.withValue(JvmFlag.ADAPTIVE_SIZE_DECREMENT_SCALE_FACTOR, value);
break;
case CMS_EXP_AVG_FACTOR:
builder.withValue(JvmFlag.CMS_EXP_AVG_FACTOR, value);
break;
case CMS_INCREMENTAL_DUTY_CYCLE:
builder.withValue(JvmFlag.CMS_INCREMENTAL_DUTY_CYCLE, value);
break;
case CMS_INCREMENTAL_DUTY_CYCLE_MIN:
builder.withValue(JvmFlag.CMS_INCREMENTAL_DUTY_CYCLE_MIN, value);
break;
case CMS_INCREMENTAL_OFFSET:
builder.withValue(JvmFlag.CMS_INCREMENTAL_OFFSET, value);
break;
case CMS_INCREMENTAL_SAFETY_FACTOR:
builder.withValue(JvmFlag.CMS_INCREMENTAL_SAFETY_FACTOR, value);
break;
case CMS_INITIATING_OCCUPANCY_FRACTION:
builder.withValue(JvmFlag.CMS_INITIATING_OCCUPANCY_FRACTION, value);
break;
case GC_TIME_RATIO:
builder.withValue(JvmFlag.GC_TIME_RATIO, value);
break;
case HEAP_SIZE:
builder.withValue(JvmFlag.HEAP_SIZE, value);
break;
case MAX_GC_PAUSE_MILLIS:
builder.withValue(JvmFlag.MAX_GC_PAUSE_MILLIS, value);
break;
case MAX_HEAP_FREE_RATIO:
builder.withValue(JvmFlag.MAX_HEAP_FREE_RATIO, value);
break;
case MIN_HEAP_FREE_RATIO:
builder.withValue(JvmFlag.MIN_HEAP_FREE_RATIO, value);
break;
case NEW_RATIO:
builder.withValue(JvmFlag.NEW_RATIO, value);
break;
case NEW_SIZE:
builder.withValue(JvmFlag.NEW_SIZE, value);
break;
case MAX_NEW_SIZE:
builder.withValue(JvmFlag.MAX_NEW_SIZE, value);
break;
case PARALLEL_GC_THREADS:
builder.withValue(JvmFlag.PARALLEL_GC_THREADS, value);
break;
case SOFT_REF_LRU_POLICY_MS_PER_MB:
builder.withValue(JvmFlag.SOFT_REF_LRU_POLICY_MS_PER_MB, value);
break;
case SURVIVOR_RATIO:
builder.withValue(JvmFlag.SURVIVOR_RATIO, value);
break;
case TENURED_GENERATION_SIZE_INCREMENT:
builder.withValue(JvmFlag.TENURED_GENERATION_SIZE_INCREMENT, value);
break;
case YOUNG_GENERATION_SIZE_INCREMENT:
builder.withValue(JvmFlag.YOUNG_GENERATION_SIZE_INCREMENT, value);
break;
case USE_CONC_MARK_SWEEP_GC:
builder.withValue(JvmFlag.USE_CONC_MARK_SWEEP_GC, value);
break;
case USE_PARALLEL_GC:
builder.withValue(JvmFlag.USE_PARALLEL_GC, value);
break;
case USE_PARALLEL_OLD_GC:
builder.withValue(JvmFlag.USE_PARALLEL_OLD_GC, value);
break;
case USE_SERIAL_GC:
builder.withValue(JvmFlag.USE_SERIAL_GC, value);
break;
case CMS_INCREMENTAL_MODE:
builder.withValue(JvmFlag.CMS_INCREMENTAL_MODE, value);
break;
case CMS_INCREMENTAL_PACING:
builder.withValue(JvmFlag.CMS_INCREMENTAL_PACING, value);
break;
case USE_CMS_INITIATING_OCCUPANCY_ONLY:
builder.withValue(JvmFlag.USE_CMS_INITIATING_OCCUPANCY_ONLY, value);
break;
}
}
final JvmFlagSet jvmFlagSet = builder.build();
bridge.storeCommandLine(jvmFlagSet);
}
experimentDb.makeExperiment(subjectIds);
}
public PipelineId pipelineId() {
return pipelineId;
}
public GroningenConfig config() {
return config;
}
public ExperimentDb experimentDb() {
return experimentDb;
}
public byte[] toBytes() {
org.arbeitspferde.groningen.proto.ExperimentDbProtos.PipelineId.Builder idProtoBuilder =
org.arbeitspferde.groningen.proto.ExperimentDbProtos.PipelineId.newBuilder();
idProtoBuilder.setId(pipelineId.id());
org.arbeitspferde.groningen.proto.ExperimentDbProtos.PipelineId idProto =
idProtoBuilder.build();
ProgramConfiguration configurationProto = config.getProtoConfig();
List<ExperimentDbProtos.Subject> subjectProtos = new ArrayList<>();
Experiment lastExperiment = experimentDb.getLastExperiment();
if (lastExperiment != null) {
// Then write out all the subjects in the experiment
final JvmFlag[] arguments = JvmFlag.values();
for (final SubjectStateBridge subject : lastExperiment.getSubjects()) {
final ExperimentDbProtos.Subject.Builder subjectBuilder =
ExperimentDbProtos.Subject.newBuilder();
subjectBuilder.setId(subject.getIdOfObject());
subjectBuilder.setIsDefault(subject.getAssociatedSubject().isDefault());
// Copy the command line
final CommandLine commandLine = subject.getCommandLine();
final ExperimentDbProtos.CommandLine.Builder commandLineBuilder =
ExperimentDbProtos.CommandLine.newBuilder();
for (final JvmFlag argument : arguments) {
final long value = commandLine.getValue(argument);
final ExperimentDbProtos.CommandLineArgument.Builder argumentBuilder =
ExperimentDbProtos.CommandLineArgument.newBuilder();
argumentBuilder.setName(argument.name());
argumentBuilder.setValue(String.valueOf(value));
commandLineBuilder.addArgument(argumentBuilder);
}
subjectBuilder.setCommandLine(commandLineBuilder);
subjectProtos.add(subjectBuilder.build());
}
}
org.arbeitspferde.groningen.proto.ExperimentDbProtos.PipelineState.Builder stateProtoBuilder =
org.arbeitspferde.groningen.proto.ExperimentDbProtos.PipelineState.newBuilder();
stateProtoBuilder.setId(idProto);
stateProtoBuilder.setConfiguration(configurationProto);
stateProtoBuilder.addAllSubjects(subjectProtos);
return stateProtoBuilder.build().toByteArray();
}
}