// This file is part of OpenTSDB.
// Copyright (C) 2010-2012 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.core;
import java.util.List;
import java.util.Map;
import org.hbase.async.Bytes.ByteMap;
import com.stumbleupon.async.Deferred;
import net.opentsdb.meta.Annotation;
/**
* Represents a read-only sequence of continuous data points.
* <p>
* Implementations of this interface aren't expected to be synchronized.
*/
public interface DataPoints extends Iterable<DataPoint> {
/**
* Returns the name of the series.
*/
String metricName();
/**
* Returns the name of the series.
* @since 1.2
*/
Deferred<String> metricNameAsync();
/**
* @return the metric UID
* @since 2.3
*/
byte[] metricUID();
/**
* Returns the tags associated with these data points.
* @return A non-{@code null} map of tag names (keys), tag values (values).
*/
Map<String, String> getTags();
/**
* Returns the tags associated with these data points.
* @return A non-{@code null} map of tag names (keys), tag values (values).
* @since 1.2
*/
Deferred<Map<String, String>> getTagsAsync();
/**
* Returns a map of tag pairs as UIDs.
* When used on a span or row, it returns the tag set. When used on a span
* group it will return only the tag pairs that are common across all
* time series in the group.
* @return A potentially empty map of tagk to tagv pairs as UIDs
* @since 2.2
*/
ByteMap<byte[]> getTagUids();
/**
* Returns the tags associated with some but not all of the data points.
* <p>
* When this instance represents the aggregation of multiple time series
* (same metric but different tags), {@link #getTags} returns the tags that
* are common to all data points (intersection set) whereas this method
* returns all the tags names that are not common to all data points (union
* set minus the intersection set, also called the symmetric difference).
* <p>
* If this instance does not represent an aggregation of multiple time
* series, the list returned is empty.
* @return A non-{@code null} list of tag names.
*/
List<String> getAggregatedTags();
/**
* Returns the tags associated with some but not all of the data points.
* <p>
* When this instance represents the aggregation of multiple time series
* (same metric but different tags), {@link #getTags} returns the tags that
* are common to all data points (intersection set) whereas this method
* returns all the tags names that are not common to all data points (union
* set minus the intersection set, also called the symmetric difference).
* <p>
* If this instance does not represent an aggregation of multiple time
* series, the list returned is empty.
* @return A non-{@code null} list of tag names.
* @since 1.2
*/
Deferred<List<String>> getAggregatedTagsAsync();
/**
* Returns the tagk UIDs associated with some but not all of the data points.
* @return a non-{@code null} list of tagk UIDs.
* @since 2.3
*/
List<byte[]> getAggregatedTagUids();
/**
* Returns a list of unique TSUIDs contained in the results
* @return an empty list if there were no results, otherwise a list of TSUIDs
*/
public List<String> getTSUIDs();
/**
* Compiles the annotations for each span into a new array list
* @return Null if none of the spans had any annotations, a list if one or
* more were found
*/
public List<Annotation> getAnnotations();
/**
* Returns the number of data points.
* <p>
* This method must be implemented in {@code O(1)} or {@code O(n)}
* where <code>n = {@link #aggregatedSize} > 0</code>.
* @return A positive integer.
*/
int size();
/**
* Returns the number of data points aggregated in this instance.
* <p>
* When this instance represents the aggregation of multiple time series
* (same metric but different tags), {@link #size} returns the number of data
* points after aggregation, whereas this method returns the number of data
* points before aggregation.
* <p>
* If this instance does not represent an aggregation of multiple time
* series, then 0 is returned.
* @return A positive integer.
*/
int aggregatedSize();
/**
* Returns a <em>zero-copy view</em> to go through {@code size()} data points.
* <p>
* The iterator returned must return each {@link DataPoint} in {@code O(1)}.
* <b>The {@link DataPoint} returned must not be stored</b> and gets
* invalidated as soon as {@code next} is called on the iterator. If you
* want to store individual data points, you need to copy the timestamp
* and value out of each {@link DataPoint} into your own data structures.
*/
SeekableView iterator();
/**
* Returns the timestamp associated with the {@code i}th data point.
* The first data point has index 0.
* <p>
* This method must be implemented in
* <code>O({@link #aggregatedSize})</code> or better.
* <p>
* It is guaranteed that <pre>timestamp(i) < timestamp(i+1)</pre>
* @return A strictly positive integer.
* @throws IndexOutOfBoundsException if {@code i} is not in the range
* <code>[0, {@link #size} - 1]</code>
*/
long timestamp(int i);
/**
* Tells whether or not the {@code i}th value is of integer type.
* The first data point has index 0.
* <p>
* This method must be implemented in
* <code>O({@link #aggregatedSize})</code> or better.
* @return {@code true} if the {@code i}th value is of integer type,
* {@code false} if it's of floating point type.
* @throws IndexOutOfBoundsException if {@code i} is not in the range
* <code>[0, {@link #size} - 1]</code>
*/
boolean isInteger(int i);
/**
* Returns the value of the {@code i}th data point as a long.
* The first data point has index 0.
* <p>
* This method must be implemented in
* <code>O({@link #aggregatedSize})</code> or better.
* Use {@link #iterator} to get successive {@code O(1)} accesses.
* @see #iterator
* @throws IndexOutOfBoundsException if {@code i} is not in the range
* <code>[0, {@link #size} - 1]</code>
* @throws ClassCastException if the
* <code>{@link #isInteger isInteger(i)} == false</code>.
*/
long longValue(int i);
/**
* Returns the value of the {@code i}th data point as a float.
* The first data point has index 0.
* <p>
* This method must be implemented in
* <code>O({@link #aggregatedSize})</code> or better.
* Use {@link #iterator} to get successive {@code O(1)} accesses.
* @see #iterator
* @throws IndexOutOfBoundsException if {@code i} is not in the range
* <code>[0, {@link #size} - 1]</code>
* @throws ClassCastException if the
* <code>{@link #isInteger isInteger(i)} == true</code>.
*/
double doubleValue(int i);
/**
* Return the query index that maps this datapoints to the original TSSubQuery.
* @return index of the query in the TSQuery class
* @throws UnsupportedOperationException if the implementing class can't map
* to a sub query.
* @since 2.2
*/
int getQueryIndex();
}