com.iobeam.api.resource.DataStore Maven / Gradle / Ivy
package com.iobeam.api.resource;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.logging.Logger;
/**
* Represents a batch of data streams in column format. That is, columns are names for
* series/streams, and each row is a timestamp plus values for (some of) the series/streams.
*
* When converted to JSON, a "time" column is prepended to the other columns which are listed in
* alphabetical order. Rows are represented as a list with the first value being the timestamp,
* followed by corresponding values for each column. If a row does not have a value for a column,
* then it is filled in with null.
*/
public class DataStore implements Serializable {
public static final class MismatchedLengthException extends RuntimeException {
public MismatchedLengthException() {
super("Number of columns and values are not the same.");
}
}
public static final class UnknownFieldException extends RuntimeException {
public UnknownFieldException(String field) {
super("Unknown field '" + field + "' trying to be added.");
}
}
public static final class ReservedColumnException extends IllegalArgumentException {
public ReservedColumnException(String column) {
super("'" + column + "' is a reserved column name.");
}
}
private static final Logger logger = Logger.getLogger(DataStore.class.getName());
private static final String KEY_COLUMNS = "fields";
private static final String KEY_ROWS = "data";
private static final String[] RESERVED_COLS = {"time", "time_offset", "all"};
private final TreeSet columns;
private final TreeMap> rows =
new TreeMap>();
/**
* Constructs a DataStore, using a collection to construct a _set_ of columns. Note: Duplicates
* will be removed and a warning will be logged.
*
* @param columns Set of field names to track in this batch.
*/
public DataStore(Collection columns) {
checkColumns(columns);
this.columns = new TreeSet(columns);
if (columns.size() != this.columns.size()) {
logger.warning("Size mismatch in provided list of columns and resulting set of " +
"columns; list may have contained duplicates.");
}
}
public DataStore(String... columns) {
this(Arrays.asList(columns));
}
private void checkColumns(Collection columns) {
for (String c : columns) {
if (c == null || c.isEmpty()) {
throw new IllegalArgumentException("Column cannot be null or empty string.");
}
if (Arrays.asList(RESERVED_COLS).contains(c.toLowerCase())) {
throw new ReservedColumnException(c);
}
}
}
/**
* Add a data row, consisting of one column, to the store at a particular time.
*
* @param timestamp Timestamp for the data point.
* @param column The column for a field to value mapping
* @param value The value for a field to value mapping
*/
public void add(long timestamp, String column, Object value) {
if (!(value instanceof Long) && !(value instanceof Integer) && !(value instanceof Double) &&
!(value instanceof Float) && !(value instanceof Boolean) &&
!(value instanceof String)) {
throw new IllegalArgumentException(
"value must be of type: Long, Integer, Double, Float, Boolean, or String");
}
Map temp = new HashMap();
temp.put(column, value);
add(timestamp, temp);
}
/**
* Add a data row, consisting of one column, to the store at the current time.
*
* See {@link #add(long, Map)} for more information.
*
* @param column The column for a field to value mapping
* @param value The value for a field to value mapping
*/
public void add(String column, Object value) {
add(System.currentTimeMillis(), column, value);
}
/**
* Add a data row to the batch at a particular timestamp.
*
* This method will throw a `MismatchedLengthException` if the length of `columns` and `values`
* are not the same.
*
* See {@link #add(long, Map)} for more information.
*
* @param timestamp Timestamp for all data points
* @param columns The list of columns for a field to value mapping
* @param values The list of values for a field to value mapping
*/
public void add(long timestamp, String[] columns, Object[] values) {
add(timestamp, Arrays.asList(columns), Arrays.asList(values));
}
/**
* Add a data row to the batch with the current time.
*
* This method will throw a `MismatchedLengthException` if the length of `columns` and `values`
* are not the same.
*
* See {@link #add(long, Map)} for more information.
*
* @param columns The list of columns for a field to value mapping
* @param values The list of values for a field to value mapping
*/
public void add(String[] columns, Object[] values) {
add(System.currentTimeMillis(), columns, values);
}
/**
* Add a data row to the batch at a particular timestamp.
*
* This method will throw a `MismatchedLengthException` if the size of `columns` and `values`
* are not the same.
*
* See {@link #add(long, Map)} for more information.
*
* @param timestamp Timestamp for all data points
* @param columns The list of columns for a field to value mapping
* @param values The list of values for a field to value mapping
*/
public void add(long timestamp, List columns, List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy