package org.yamcs.parameterarchive;
import java.util.ArrayList;
import java.util.List;
import org.yamcs.parameter.ParameterValue;
import org.yamcs.parameter.Value;
import org.yamcs.protobuf.Yamcs.Value.Type;
import org.yamcs.utils.SortedIntArray;
/**
* Parameter Group segment - keeps references to Time and Value segments for a given parameter group and segment.
*
* This class is used during the parameter archive buildup
* - it uses GenericValueSegment to store any kind of Value
* - once the segment is full, the consolidate method will turn each GenericValueSegment into an storage optimised one.
*
*
* @author nm
*
*/
public class PGSegment {
final int parameterGroupId;
final SortedIntArray parameterIds;
private SortedTimeSegment timeSegment;
private List<ValueSegment> engValueSegments;
private List<ValueSegment> rawValueSegments;
private List<ParameterStatusSegment> parameterStatusSegments;
private List<BaseSegment> consolidatedValueSegments;
private List<BaseSegment> consolidatedRawValueSegments;
private List<ParameterStatusSegment> consolidatedParameterStatusSegments;
private final boolean storeRawValues = ParameterArchive.STORE_RAW_VALUES;
private long segmentStart;
public PGSegment(int parameterGroupId, long segmentStart, SortedIntArray parameterIds) {
this.parameterGroupId = parameterGroupId;
this.parameterIds = parameterIds;
this.segmentStart = segmentStart;
}
private void init(List<ParameterValue> sortedPvList) {
timeSegment = new SortedTimeSegment(segmentStart);
engValueSegments = new ArrayList<>(parameterIds.size());
parameterStatusSegments = new ArrayList<>(parameterIds.size());
if(storeRawValues) {
rawValueSegments = new ArrayList<>(parameterIds.size());
}
for(int i=0; i<parameterIds.size(); i++) {
ParameterValue pv = sortedPvList.get(i);
Value v = pv.getEngValue();
if(v!=null) {
engValueSegments.add(getNewSegment(v.getType()));
}
parameterStatusSegments.add(new ParameterStatusSegment(true));
Value rawV = pv.getRawValue();
if(storeRawValues) {
if(rawV==null) {
rawValueSegments.add(null);
} else {
rawValueSegments.add(getNewSegment(rawV.getType()));
}
}
}
}
static private ValueSegment getNewSegment(Type type) {
switch(type) {
case BINARY:
return new BinaryValueSegment(true);
case STRING:
return new StringValueSegment(true);
case SINT32:
return new IntValueSegment(true);
case UINT32:
return new IntValueSegment(false);
case FLOAT:
return new FloatValueSegment();
case SINT64:
return new LongValueSegment(true);
case UINT64:
return new LongValueSegment(false);
case DOUBLE:
return new DoubleValueSegment();
default:
return new GenericValueSegment();
}
}
/**
* Add a new record
* instant goes into the timeSegment
* the values goes each into a value segment
*
* the sortedPvList list has to be already sorted according to the definition of the ParameterGroup
*
*
* @param instant
* @param sortedPvList
*/
public void addRecord(long instant, List<ParameterValue> sortedPvList) {
if(sortedPvList.size() != parameterIds.size()) {
throw new IllegalArgumentException("Wrong number of values passed: "+sortedPvList.size()+";expected "+engValueSegments.size());
}
if(engValueSegments==null) {
init(sortedPvList);
}
int pos = timeSegment.add(instant);
for(int i = 0; i<engValueSegments.size(); i++) {
ParameterValue pv = sortedPvList.get(i);
engValueSegments.get(i).add(pos, pv.getEngValue());
Value rawValue = pv.getRawValue();
if(storeRawValues && (rawValue!=null)) {
rawValueSegments.get(i).add(pos, rawValue);
}
parameterStatusSegments.get(i).addParameterValue(pos, pv);
}
}
public void consolidate() {
consolidatedValueSegments = new ArrayList<BaseSegment>(engValueSegments.size());
for(ValueSegment gvs: engValueSegments) {
BaseSegment bs = gvs.consolidate();
consolidatedValueSegments.add(bs);
}
if(storeRawValues && rawValueSegments.size()>0) {
consolidatedRawValueSegments = new ArrayList<BaseSegment>(engValueSegments.size());
//the raw values will only be stored if they are different than the engineering values
for(int i=0; i<engValueSegments.size(); i++) {
ValueSegment rvs = rawValueSegments.get(i);
ValueSegment vs = engValueSegments.get(i);
if((rvs==null) || rvs.equals(vs)) {
consolidatedRawValueSegments.add(null);
} else {
consolidatedRawValueSegments.add(rvs.consolidate());
}
}
}
consolidatedParameterStatusSegments = new ArrayList<>(parameterStatusSegments.size());
for(int i=0;i<engValueSegments.size(); i++) {
consolidatedParameterStatusSegments.add(parameterStatusSegments.get(i).consolidate());
}
}
public long getSegmentStart() {
return timeSegment.getSegmentStart();
}
public SortedTimeSegment getTimeSegment() {
return timeSegment;
}
public int getParameterGroupId() {
return parameterGroupId;
}
public int getParameterId(int index) {
return parameterIds.get(index);
}
public List<BaseSegment> getConsolidatedValueSegments() {
return consolidatedValueSegments;
}
public List<BaseSegment> getConsolidatedRawValueSegments() {
return consolidatedRawValueSegments;
}
public List<ParameterStatusSegment> getConsolidatedParameterStatusSegments() {
return consolidatedParameterStatusSegments;
}
}