// This file is part of OpenTSDB.
// Copyright (C) 2015 The OpenTSDB Authors.
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2.1 of the License, or (at your
// option) any later version. This program is distributed in the hope that it
// will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details. You should have received a copy
// of the GNU Lesser General Public License along with this program. If not,
// see <http://www.gnu.org/licenses/>.
package net.opentsdb.query.expression;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* An interface that helps merge different time series sets (e.g. different
* metrics with a group by operator). The implementations handle joining the
* two sets according to the {@link SetOperator}.
* @since 2.3
*/
public interface VariableIterator {
/** An operator that determines how to sets of time series are merged via
* expression. */
public enum SetOperator {
/** A union, meaning results from all sets will appear, using FillPolicies
* for missing series */
UNION("union"),
/** Computes the intersection, returning results only for series that appear
* in all sets */
INTERSECTION("intersection");
/** The user-friendly name of this operator. */
private final String name;
/** @param the readable name of the operator */
SetOperator(final String name) {
this.name = name;
}
/** @return the readable name of the operator */
@JsonValue
public String getName() {
return name;
}
/**
* Converts a string to lower case then looks up the operator
* @param name The name to find an operator for
* @return The operator if found.
* @throws IllegalArgumentException if the operator wasn't found
*/
@JsonCreator
public static SetOperator fromString(final String name) {
for (final SetOperator operator : SetOperator.values()) {
if (operator.name.equalsIgnoreCase(name)) {
return operator;
}
}
throw new IllegalArgumentException("Unrecognized set operator: " + name);
}
}
/**
* Whether or not another set of results are available. Always call this
* before calling next.
* @return True if more results are available, false if not.
*/
public boolean hasNext();
/**
* Iterates the {@link getResults()} to the next set of results. If there
* aren't any results left, the implementation may throw an exception. Always
* call {@link hasNext()} first.
*/
public void next();
/**
* Determines whether the individual series in the {@link values} array has
* another value. This may be used for non-synchronous iteration.
* @param index The index of the series in the values array to check for
* @return True if the series has another value, false if not
*/
public boolean hasNext(final int index);
/**
* Fetches the next value for an individual series in the {@link values} array.
* @param index The index of the series in the values array to advance
*/
public void next(final int index);
/**
* Returns a map of variable names to result series. You can maintain the
* reference returned without having to call getResults() on every iteration.
* Calling {@link next()} will simply update the ExpressionDataPoint array.
* The implementation may return a null map if there weren't any results
* available. Always all {@link hasNext()} before getting the results.
* @return A map with results to read from.
*/
public Map<String, ExpressionDataPoint[]> getResults();
/** @return The number of time series after the join. This should match the
* number of entries in the results data point array, not the number of
* variables in the results map. */
public int getSeriesSize();
/** @return the next timestamp for all results without iterating */
public long nextTimestamp();
}