/**
* Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT
* All rights reserved. Use is subject to license terms. See LICENSE.TXT
*/
package org.diirt.datasource.timecache;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import org.diirt.datasource.BasicTypeSupport;
import org.diirt.datasource.ReadFunction;
import org.diirt.datasource.expression.DesiredRateExpression;
import org.diirt.datasource.expression.DesiredRateExpressionImpl;
import org.diirt.datasource.expression.DesiredRateExpressionListImpl;
import org.diirt.datasource.timecache.impl.SimpleFileDataSource;
import org.diirt.datasource.timecache.impl.SimpleMemoryStorage;
import org.diirt.datasource.timecache.query.Query;
import org.diirt.datasource.timecache.query.QueryData;
import org.diirt.datasource.timecache.query.QueryParameters;
import org.diirt.datasource.timecache.query.QueryResult;
import org.diirt.datasource.timecache.util.CacheHelper;
import org.diirt.datasource.vtype.DataTypeSupport;
import org.diirt.util.array.ArrayDouble;
import org.diirt.vtype.VDouble;
import org.diirt.vtype.VTable;
import org.diirt.vtype.VType;
import org.diirt.vtype.ValueFactory;
/**
* PVManager expression language support for additional operations.
*
* @author carcassi
*/
public class ExpressionLanguage {
private ExpressionLanguage() {
}
static {
// Add support for Epics types.
DataTypeSupport.install();
// Add support for Basic types
BasicTypeSupport.install();
}
/**
* A query expression that returns the result formatted as a table.
*
* @param channelName
* @param parameters
* @return a new expression
*/
public static DesiredRateExpression<VTable> timeTableOf(
final String channelName, QueryParameters parameters) {
// TODO: Cache & query should not be created here in order to be
// configured / closed
CacheConfig config = new CacheConfig();
config.addSource(new SimpleFileDataSource("src/test/resources/archive-export.csv"));
config.addSource(new SimpleFileDataSource("src/test/resources/archive-export-singlePV.csv"));
config.setStorage(new SimpleMemoryStorage());
final Cache cache = CacheFactory.getCache(config);
final Query query = cache.createQuery(channelName, VType.class, parameters);
return new DesiredRateExpressionImpl<VTable>(new DesiredRateExpressionListImpl<Object>(),
new ReadFunction<VTable>() {
private NavigableMap<Instant, Double> valueMap;
private VTable previousValue;
{
valueMap = new ConcurrentSkipListMap<Instant, Double>();
previousValue = ValueFactory.newVTable(Arrays.<Class<?>> asList(String.class, double.class),
Arrays.asList("Time", "Value"),
Arrays.asList(Arrays.asList(channelName), new ArrayDouble(0)));
}
@Override
public VTable readValue() {
// Create table by merging chunks as they come
// Get new data
QueryResult result = query.getUpdate();
// If not new data is available, return the previous table
if (result.getData().isEmpty())
return previousValue;
int index = 0;
for (QueryData data : result.getData()) {
for (VType dataToDisplay : data.getData()) {
if (dataToDisplay instanceof VDouble)
valueMap.put(data.getTimestamps().get(index), ((VDouble) dataToDisplay).getValue());
index++;
}
}
index = 0;
double[] array = new double[valueMap.size()];
List<String> times = new ArrayList<String>();
for (Entry<Instant, Double> entry : valueMap.entrySet()) {
times.add(CacheHelper.format(entry.getKey()));
array[index] = entry.getValue();
index++;
}
previousValue = ValueFactory.newVTable(Arrays.<Class<?>> asList(String.class, double.class),
Arrays.asList("Time", "Value"),
Arrays.asList(times, new ArrayDouble(array, true)));
return previousValue;
}
}, channelName);
}
}