mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-11-14 06:46:56 +00:00
refactor(datatypes): name the PromQL series label set by what it is
`MetricName` held the whole PromQL-visible label set of a series -- the `__name__` value plus its ordinary labels -- not one metric name. Rename it to `SeriesLabels` so the type says what it holds, and record in its doc comment that it is neither a canonical matching/grouping identity nor a storage identity. Signed-off-by: discord9 <discord9@163.com>
This commit is contained in:
@@ -47,7 +47,7 @@ use datatypes::series::frame::{
|
||||
};
|
||||
use datatypes::series::raw::RawSeriesChunk;
|
||||
use datatypes::series::samples::SeriesSchema;
|
||||
use datatypes::series::{MetricName, SeriesOrdering};
|
||||
use datatypes::series::{SeriesLabels, SeriesOrdering};
|
||||
use futures_util::Stream;
|
||||
use store_api::codec::PrimaryKeyEncoding;
|
||||
use store_api::region_engine::{
|
||||
@@ -380,7 +380,7 @@ struct SequenceValidator {
|
||||
ordering: SeriesOrdering,
|
||||
previous_key: Option<Vec<u8>>,
|
||||
previous_timestamp: Option<i64>,
|
||||
previous_metric: Option<MetricName>,
|
||||
previous_metric: Option<SeriesLabels>,
|
||||
previous_is_last: bool,
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ use datafusion_common::{DataFusionError, Result as DfResult};
|
||||
use datatypes::arrow_array::string_array_value_at_index;
|
||||
use datatypes::series::raw::{RawSeriesChunk, RawTimestamps};
|
||||
use datatypes::series::samples::{FieldSpec, Samples, SeriesFields, SeriesSchema};
|
||||
use datatypes::series::{Label, MetricName, SeriesOrdering};
|
||||
use datatypes::series::{Label, SeriesLabels, SeriesOrdering};
|
||||
use futures_util::Stream;
|
||||
use snafu::Location;
|
||||
use store_api::region_engine::{RawLabelSource, RawSeriesStream, SendableRawSeriesStream};
|
||||
@@ -132,8 +132,8 @@ fn validate_mapping(
|
||||
return Err(invalid("field must be Float64 or native histogram"));
|
||||
}
|
||||
}
|
||||
// MetricName validates logical label names and duplicate tags through its canonical path.
|
||||
MetricName::try_new(
|
||||
// SeriesLabels validates logical label names and duplicate tags through its canonical path.
|
||||
SeriesLabels::try_new(
|
||||
mapping.metric_name.clone(),
|
||||
mapping
|
||||
.tags
|
||||
@@ -274,7 +274,7 @@ impl InputStream {
|
||||
});
|
||||
}
|
||||
}
|
||||
let metric = MetricName::try_new(metric_name, labels).map_err(codec_error)?;
|
||||
let metric = SeriesLabels::try_new(metric_name, labels).map_err(codec_error)?;
|
||||
RawSeriesChunk::try_new(
|
||||
&self.schema,
|
||||
Buffer::from(key),
|
||||
|
||||
@@ -32,7 +32,7 @@ use datatypes::arrow::datatypes::{DataType, Schema, SchemaRef};
|
||||
use datatypes::arrow::ipc::{reader::StreamReader, writer::StreamWriter};
|
||||
use datatypes::arrow::record_batch::RecordBatch;
|
||||
use datatypes::series::Label;
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::SeriesOrdering;
|
||||
use datatypes::series::frame::{LabelDecodeSpec, RawLabelMode, raw_series_frame_schema};
|
||||
use datatypes::series::histogram::{BucketSideView, CounterResetHint, HistogramBatchBuilder};
|
||||
@@ -59,11 +59,11 @@ fn schema() -> Arc<SeriesSchema> {
|
||||
eval_grid: None,
|
||||
})
|
||||
}
|
||||
fn metric() -> MetricName {
|
||||
MetricName::try_new(Some(Arc::from("cpu")), vec![]).unwrap()
|
||||
fn metric() -> SeriesLabels {
|
||||
SeriesLabels::try_new(Some(Arc::from("cpu")), vec![]).unwrap()
|
||||
}
|
||||
fn labeled_metric(host: &str) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn labeled_metric(host: &str) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(Arc::from("cpu")),
|
||||
vec![Label {
|
||||
name: Arc::from("host"),
|
||||
@@ -76,7 +76,7 @@ fn chunk_with(
|
||||
key: &[u8],
|
||||
times: &[i64],
|
||||
values: Vec<Option<f64>>,
|
||||
metric: Option<MetricName>,
|
||||
metric: Option<SeriesLabels>,
|
||||
last: bool,
|
||||
) -> RawSeriesChunk {
|
||||
RawSeriesChunk::try_new(
|
||||
|
||||
@@ -25,7 +25,7 @@ use datatypes::series::raw::{RawSeriesChunk, RawTimestamps};
|
||||
use datatypes::series::samples::{
|
||||
DenseSamplesRef, FieldSpec, HistogramSamples, SampleRef, Samples, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
use futures_util::{Stream, StreamExt};
|
||||
use store_api::region_engine::{RawLabelSource, RawSeriesStream, SendableRawSeriesStream};
|
||||
|
||||
@@ -167,7 +167,7 @@ async fn streaming_round_trip_preserves_sliced_multifield_payload_and_owners() {
|
||||
&schema,
|
||||
Buffer::from(vec![0xaa_u8, 0x10, 0xbb]),
|
||||
Some(
|
||||
MetricName::try_new(
|
||||
SeriesLabels::try_new(
|
||||
Some(Arc::from("cpu")),
|
||||
vec![Label {
|
||||
name: Arc::from("host"),
|
||||
@@ -361,7 +361,7 @@ async fn single_row_sliced_payload_keeps_zero_copy_buffers_and_releases_owners()
|
||||
.into(),
|
||||
eval_grid: None,
|
||||
});
|
||||
let metric = MetricName::try_new(
|
||||
let metric = SeriesLabels::try_new(
|
||||
Some(Arc::from("cpu")),
|
||||
vec![Label {
|
||||
name: Arc::from("host"),
|
||||
|
||||
@@ -55,14 +55,20 @@ pub struct Label {
|
||||
pub value: Arc<str>,
|
||||
}
|
||||
|
||||
/// A metric name and its name-sorted ordinary labels.
|
||||
/// The PromQL-visible labels of one series: an optional metric name (`__name__`)
|
||||
/// plus its name-sorted ordinary labels.
|
||||
///
|
||||
/// The metric name is only the `__name__` value (see [`Self::name`]); this type is
|
||||
/// the whole label set a PromQL series shows. It is neither a canonical
|
||||
/// matching/grouping identity (matching drops `__name__` and compares the remaining
|
||||
/// labels canonically) nor a storage identity (read key / primary key).
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MetricName {
|
||||
pub struct SeriesLabels {
|
||||
name: Option<Arc<str>>,
|
||||
tags: Arc<[Label]>,
|
||||
}
|
||||
|
||||
impl MetricName {
|
||||
impl SeriesLabels {
|
||||
/// Creates a metric name, sorting labels and rejecting duplicates or `__name__` tags.
|
||||
pub fn try_new(name: Option<Arc<str>>, mut tags: Vec<Label>) -> Result<Self> {
|
||||
tags.sort_unstable_by(|a, b| a.name.cmp(&b.name));
|
||||
|
||||
@@ -76,7 +76,7 @@ use crate::series::raw::{RawSeriesChunk, RawTimestamps};
|
||||
use crate::series::samples::{
|
||||
DenseSamplesRef, FieldSpec, HistogramSamples, Samples, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use crate::series::{Label, MetricName, invalid_series};
|
||||
use crate::series::{Label, SeriesLabels, invalid_series};
|
||||
|
||||
const LAYOUT: &str = "greptime.series.layout";
|
||||
const CONTENT: &str = "greptime.series.content";
|
||||
@@ -735,7 +735,7 @@ pub fn pack_raw_series_chunk(
|
||||
/// encoded-size measure.
|
||||
struct RawFrameRow {
|
||||
primary_key: Buffer,
|
||||
metric: Option<MetricName>,
|
||||
metric: Option<SeriesLabels>,
|
||||
is_last: bool,
|
||||
times: ScalarBuffer<i64>,
|
||||
samples: Vec<Samples>,
|
||||
@@ -1000,7 +1000,7 @@ fn encode_rows(
|
||||
if mode == RawLabelMode::Explicit {
|
||||
columns.push(Arc::new(
|
||||
rows.iter()
|
||||
.map(|row| row.metric.as_ref().and_then(MetricName::name))
|
||||
.map(|row| row.metric.as_ref().and_then(SeriesLabels::name))
|
||||
.collect::<StringArray>(),
|
||||
));
|
||||
let DataType::List(label_item) = schema.field(5).data_type() else {
|
||||
@@ -1252,7 +1252,7 @@ fn decode_raw_series_frame(
|
||||
value: Arc::from(lv.value(i)),
|
||||
})
|
||||
.collect();
|
||||
Some(MetricName::try_new(
|
||||
Some(SeriesLabels::try_new(
|
||||
(!ns.is_null(row)).then(|| Arc::from(ns.value(row))),
|
||||
tags,
|
||||
)?)
|
||||
|
||||
@@ -28,7 +28,7 @@ use crate::series::histogram::{BucketSideView, CounterResetHint, HistogramBatchB
|
||||
use crate::series::samples::{
|
||||
DenseSamplesRef, FieldSpec, SampleRef, Samples, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use crate::series::{Label, MetricName};
|
||||
use crate::series::{Label, SeriesLabels};
|
||||
|
||||
fn test_schema(names: &[&str]) -> SeriesSchema {
|
||||
SeriesSchema {
|
||||
@@ -43,8 +43,8 @@ fn test_schema(names: &[&str]) -> SeriesSchema {
|
||||
}
|
||||
}
|
||||
|
||||
fn metric(name: Option<&str>, labels: &[(&str, &str)]) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn metric(name: Option<&str>, labels: &[(&str, &str)]) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
name.map(Arc::from),
|
||||
labels
|
||||
.iter()
|
||||
@@ -60,7 +60,7 @@ fn metric(name: Option<&str>, labels: &[(&str, &str)]) -> MetricName {
|
||||
fn float_chunk(
|
||||
schema: &SeriesSchema,
|
||||
key: &[u8],
|
||||
metric: Option<MetricName>,
|
||||
metric: Option<SeriesLabels>,
|
||||
times: Vec<i64>,
|
||||
values: Vec<Option<f64>>,
|
||||
is_last: bool,
|
||||
|
||||
@@ -20,7 +20,7 @@ use snafu::OptionExt;
|
||||
|
||||
use crate::error::{InvalidSeriesSnafu, Result};
|
||||
use crate::series::samples::{SeriesFields, SeriesSchema};
|
||||
use crate::series::{MetricName, invalid_series};
|
||||
use crate::series::{SeriesLabels, invalid_series};
|
||||
|
||||
/// Strictly increasing source timestamps in milliseconds for a raw series chunk.
|
||||
///
|
||||
@@ -98,7 +98,7 @@ pub struct RawSeriesChunk {
|
||||
pub primary_key: Buffer,
|
||||
/// `None` denotes an encoded key under bound-label mode; `Some` contains complete
|
||||
/// explicit labels and retains their identity.
|
||||
pub metric: Option<MetricName>,
|
||||
pub metric: Option<SeriesLabels>,
|
||||
/// Source timestamps aligned with every field.
|
||||
pub time: RawTimestamps,
|
||||
/// Field values aligned with the source timestamps.
|
||||
@@ -116,7 +116,7 @@ impl RawSeriesChunk {
|
||||
pub fn try_new(
|
||||
schema: &SeriesSchema,
|
||||
primary_key: Buffer,
|
||||
metric: Option<MetricName>,
|
||||
metric: Option<SeriesLabels>,
|
||||
time: RawTimestamps,
|
||||
fields: SeriesFields,
|
||||
is_last: bool,
|
||||
|
||||
@@ -20,7 +20,7 @@ use arrow::buffer::{Buffer, ScalarBuffer};
|
||||
use super::*;
|
||||
use crate::series::samples::{FieldSpec, SampleRef, Samples, SeriesFields, SeriesSchema};
|
||||
use crate::series::time::{EvalGrid, GridSpec};
|
||||
use crate::series::{Label, MetricName};
|
||||
use crate::series::{Label, SeriesLabels};
|
||||
|
||||
fn schema(names: &[&str]) -> SeriesSchema {
|
||||
SeriesSchema {
|
||||
@@ -35,8 +35,8 @@ fn schema(names: &[&str]) -> SeriesSchema {
|
||||
}
|
||||
}
|
||||
|
||||
fn metric() -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn metric() -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(Arc::from("cpu")),
|
||||
vec![Label {
|
||||
name: Arc::from("host"),
|
||||
|
||||
@@ -19,7 +19,7 @@ use arrow::compute::concat;
|
||||
use snafu::OptionExt;
|
||||
|
||||
use crate::error::{InvalidSeriesSnafu, Result};
|
||||
use crate::series::MetricName;
|
||||
use crate::series::SeriesLabels;
|
||||
use crate::series::histogram::{HistogramBatch, HistogramView};
|
||||
use crate::series::time::{EvalGrid, TimeAxis};
|
||||
|
||||
@@ -678,7 +678,7 @@ pub struct SeriesSchema {
|
||||
/// A validated metric, time axis, and aligned fields.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Series {
|
||||
pub metric: MetricName,
|
||||
pub metric: SeriesLabels,
|
||||
pub time: TimeAxis,
|
||||
pub fields: SeriesFields,
|
||||
}
|
||||
@@ -686,7 +686,7 @@ impl Series {
|
||||
/// Construct after validating schema, field lengths, and strictly increasing timestamps.
|
||||
pub fn try_new(
|
||||
schema: &SeriesSchema,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
time: TimeAxis,
|
||||
fields: SeriesFields,
|
||||
) -> Result<Self> {
|
||||
|
||||
@@ -996,7 +996,7 @@ fn fields_clone_buffers_and_series_validate_schema_alignment_and_time_order() {
|
||||
]),
|
||||
eval_grid: None,
|
||||
};
|
||||
let metric = MetricName::try_new(None, vec![]).unwrap();
|
||||
let metric = SeriesLabels::try_new(None, vec![]).unwrap();
|
||||
let time = TimeAxis::Explicit(ScalarBuffer::from(vec![1, 2]));
|
||||
assert!(
|
||||
Series::try_new(
|
||||
@@ -1040,7 +1040,7 @@ fn float_fields_clones_and_series_keep_real_arrow_buffer_owner_alive() {
|
||||
};
|
||||
let series = Series::try_new(
|
||||
&schema,
|
||||
MetricName::try_new(None, vec![]).unwrap(),
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
TimeAxis::Explicit(ScalarBuffer::from(vec![1_i64, 2])),
|
||||
fields,
|
||||
)
|
||||
@@ -1071,7 +1071,7 @@ fn series_enforces_grid_policy_and_matches_grid_spec_by_value() {
|
||||
let equal_grid = Arc::new(EvalGrid::try_new(spec).unwrap());
|
||||
let range = GridRange::try_new(equal_grid, 1, 1).unwrap();
|
||||
let fields = SeriesFields::one(Samples::from_float(Float64Array::from(vec![1.0])));
|
||||
let metric = MetricName::try_new(None, vec![]).unwrap();
|
||||
let metric = SeriesLabels::try_new(None, vec![]).unwrap();
|
||||
let grid_schema = SeriesSchema {
|
||||
fields: Arc::from([FieldSpec {
|
||||
name: Arc::from("value"),
|
||||
@@ -1226,7 +1226,7 @@ fn short_multifield_series_uses_its_grid_range_and_checks_explicit_chunk_order()
|
||||
};
|
||||
let series = Series::try_new(
|
||||
&schema,
|
||||
MetricName::try_new(None, vec![]).unwrap(),
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
TimeAxis::Grid(GridRange::try_new(grid, 800, 20).unwrap()),
|
||||
fields.clone(),
|
||||
)
|
||||
@@ -1266,7 +1266,7 @@ fn short_multifield_series_uses_its_grid_range_and_checks_explicit_chunk_order()
|
||||
assert!(
|
||||
Series::try_new(
|
||||
&explicit_schema,
|
||||
MetricName::try_new(None, vec![]).unwrap(),
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
out_of_order,
|
||||
explicit_fields,
|
||||
)
|
||||
@@ -1285,7 +1285,7 @@ fn short_multifield_series_uses_its_grid_range_and_checks_explicit_chunk_order()
|
||||
assert!(
|
||||
Series::try_new(
|
||||
&explicit_schema,
|
||||
MetricName::try_new(None, vec![]).unwrap(),
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
ordered_chunks.clone(),
|
||||
ordered_fields.clone(),
|
||||
)
|
||||
@@ -1299,7 +1299,7 @@ fn short_multifield_series_uses_its_grid_range_and_checks_explicit_chunk_order()
|
||||
assert!(
|
||||
Series::try_new(
|
||||
&grid_schema,
|
||||
MetricName::try_new(None, vec![]).unwrap(),
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
ordered_chunks,
|
||||
ordered_fields,
|
||||
)
|
||||
@@ -1311,7 +1311,7 @@ fn short_multifield_series_uses_its_grid_range_and_checks_explicit_chunk_order()
|
||||
fn series_accepts_a_sparse_axis_on_its_schema_grid_only() {
|
||||
let spec = GridSpec::try_new(100, 10, 5).unwrap();
|
||||
let schema_grid = Arc::new(EvalGrid::try_new(spec).unwrap());
|
||||
let metric = MetricName::try_new(None, vec![]).unwrap();
|
||||
let metric = SeriesLabels::try_new(None, vec![]).unwrap();
|
||||
let schema = SeriesSchema {
|
||||
fields: Arc::from([FieldSpec {
|
||||
name: Arc::from("value"),
|
||||
@@ -1396,7 +1396,7 @@ fn series_accepts_a_sparse_axis_on_its_schema_grid_only() {
|
||||
assert!(
|
||||
Series::try_new(
|
||||
&schema,
|
||||
MetricName::try_new(None, vec![]).unwrap(),
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
TimeAxis::GridRanges(ranges()),
|
||||
empty_fields
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::{Label, MetricName};
|
||||
use super::{Label, SeriesLabels};
|
||||
|
||||
fn label(name: &str, value: &str) -> Label {
|
||||
Label {
|
||||
@@ -25,7 +25,7 @@ fn label(name: &str, value: &str) -> Label {
|
||||
|
||||
#[test]
|
||||
fn metric_name_sorts_labels_and_rejects_ambiguous_identity() {
|
||||
let metric = MetricName::try_new(
|
||||
let metric = SeriesLabels::try_new(
|
||||
Some(Arc::from("cpu")),
|
||||
vec![label("zone", "west"), label("host", "node-1")],
|
||||
)
|
||||
@@ -34,18 +34,18 @@ fn metric_name_sorts_labels_and_rejects_ambiguous_identity() {
|
||||
assert_eq!(metric.tags()[0].name.as_ref(), "host");
|
||||
assert_eq!(metric.tags()[1].name.as_ref(), "zone");
|
||||
|
||||
assert!(MetricName::try_new(None, vec![label("x", "1"), label("x", "2")]).is_err());
|
||||
assert!(MetricName::try_new(None, vec![label("__name__", "cpu")]).is_err());
|
||||
assert!(SeriesLabels::try_new(None, vec![label("x", "1"), label("x", "2")]).is_err());
|
||||
assert!(SeriesLabels::try_new(None, vec![label("__name__", "cpu")]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn metric_identity_uses_contents_and_distinguishes_absent_from_empty() {
|
||||
let one = MetricName::try_new(
|
||||
let one = SeriesLabels::try_new(
|
||||
Some(Arc::from(String::from("cpu"))),
|
||||
vec![label("empty", ""), label("host", "a")],
|
||||
)
|
||||
.unwrap();
|
||||
let same = MetricName::try_new(
|
||||
let same = SeriesLabels::try_new(
|
||||
Some(Arc::from(String::from("cpu"))),
|
||||
vec![label("host", "a"), label("empty", "")],
|
||||
)
|
||||
@@ -58,7 +58,7 @@ fn metric_identity_uses_contents_and_distinguishes_absent_from_empty() {
|
||||
|
||||
#[test]
|
||||
fn metric_name_edits_retain_shared_labels_and_labels_are_copy_on_write() {
|
||||
let mut metric = MetricName::try_new(
|
||||
let mut metric = SeriesLabels::try_new(
|
||||
Some(Arc::from("cpu")),
|
||||
vec![label("host", "a"), label("zone", "west")],
|
||||
)
|
||||
@@ -89,7 +89,7 @@ fn metric_name_edits_retain_shared_labels_and_labels_are_copy_on_write() {
|
||||
|
||||
#[test]
|
||||
fn keep_only_and_remove_all_handle_metric_name_and_ordinary_labels() {
|
||||
let mut metric = MetricName::try_new(
|
||||
let mut metric = SeriesLabels::try_new(
|
||||
Some(Arc::from("cpu")),
|
||||
vec![label("host", "a"), label("zone", "west")],
|
||||
)
|
||||
|
||||
@@ -643,7 +643,7 @@ mod acceptance {
|
||||
use arrow::array::Float64Array;
|
||||
|
||||
use super::super::{EvalGrid, GridRanges, GridSpan, GridSpec, TimeAxis};
|
||||
use crate::series::MetricName;
|
||||
use crate::series::SeriesLabels;
|
||||
use crate::series::samples::{
|
||||
FieldSpec, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
};
|
||||
@@ -692,7 +692,7 @@ mod acceptance {
|
||||
]));
|
||||
let series = Series::try_new(
|
||||
&schema,
|
||||
MetricName::try_new(Some(Arc::from("m")), vec![]).unwrap(),
|
||||
SeriesLabels::try_new(Some(Arc::from("m")), vec![]).unwrap(),
|
||||
time,
|
||||
SeriesFields::try_from_vec(vec![a, b]).unwrap(),
|
||||
)
|
||||
|
||||
@@ -19,7 +19,7 @@ use api::v1::SemanticType;
|
||||
use common_telemetry::debug;
|
||||
use datatypes::data_type::ConcreteDataType;
|
||||
use datatypes::series::frame::{LabelDecodeEncoding, LabelDecodeSpec};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
use datatypes::value::Value;
|
||||
use snafu::{OptionExt, ResultExt};
|
||||
use store_api::codec::PrimaryKeyEncoding;
|
||||
@@ -53,7 +53,7 @@ pub enum LabelProjection {
|
||||
/// Decoded labels: either a complete metric name or a possibly partial label vector.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum DecodedLabels {
|
||||
Complete(MetricName),
|
||||
Complete(SeriesLabels),
|
||||
Projected(Vec<Label>),
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ impl PrimaryKeyLabelDecoder {
|
||||
|
||||
/// Decodes labels without modifying or consuming `read_key`.
|
||||
///
|
||||
/// `All` returns a complete [`MetricName`]; `Only` returns a partial vector. Dense
|
||||
/// `All` returns a complete [`SeriesLabels`]; `Only` returns a partial vector. Dense
|
||||
/// keys are fully checked against the exact snapshot layout even when decoding only
|
||||
/// selected fields. Sparse keys receive a full structural audit before values are read.
|
||||
pub fn decode(&mut self, read_key: &[u8]) -> Result<DecodedLabels> {
|
||||
@@ -353,7 +353,7 @@ impl PrimaryKeyLabelDecoder {
|
||||
}
|
||||
if *complete {
|
||||
Ok(DecodedLabels::Complete(
|
||||
MetricName::try_new(Some(key.metric_name.clone()), values).map_err(|error| {
|
||||
SeriesLabels::try_new(Some(key.metric_name.clone()), values).map_err(|error| {
|
||||
InvalidSparsePrimaryKeySnafu {
|
||||
reason: error.to_string(),
|
||||
}
|
||||
|
||||
@@ -6245,7 +6245,7 @@ impl store_api::region_engine::RawSeriesStream for ChainedRawSeriesStream {
|
||||
fn decode_declared_labels(
|
||||
description: &datatypes::series::frame::LabelDecodeSpec,
|
||||
chunks: &[datatypes::series::raw::RawSeriesChunk],
|
||||
) -> Vec<datatypes::series::MetricName> {
|
||||
) -> Vec<datatypes::series::SeriesLabels> {
|
||||
use mito_codec::labels::{DecodedLabels, LabelProjection, PrimaryKeyLabelDecoder};
|
||||
|
||||
let mut decoder =
|
||||
|
||||
@@ -32,7 +32,7 @@ use std::sync::Arc;
|
||||
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::arrow::array::Float64Array;
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::samples::{SampleRef, Samples, Series, SeriesSchema};
|
||||
use datatypes::series::time::{GridSpan, TimeAxis};
|
||||
|
||||
@@ -506,7 +506,7 @@ pub fn aggregate_quantile(
|
||||
.collect();
|
||||
// Members keep input order, the order Prometheus appends to its per-step heap.
|
||||
let mut group_index = HashMap::new();
|
||||
let mut groups: Vec<(MetricName, Vec<&Series>)> = Vec::new();
|
||||
let mut groups: Vec<(SeriesLabels, Vec<&Series>)> = Vec::new();
|
||||
for series in input {
|
||||
let metric = grouping.apply(&series.metric)?;
|
||||
let index = *group_index.entry(label_key(&metric)).or_insert_with(|| {
|
||||
@@ -670,7 +670,7 @@ pub fn count_values(
|
||||
}
|
||||
|
||||
/// Counts per point and field: one series per label set, a count of 0 being no sample.
|
||||
type Counts = Vec<(MetricName, BTreeMap<usize, Vec<f64>>)>;
|
||||
type Counts = Vec<(SeriesLabels, BTreeMap<usize, Vec<f64>>)>;
|
||||
|
||||
fn count_series(schema: &Arc<SeriesSchema>, groups: Counts) -> Result<Vec<Series>> {
|
||||
let mut builder = GridSeriesBuilder::try_new(schema.clone())?;
|
||||
@@ -729,7 +729,7 @@ impl Grouping<'_> {
|
||||
}
|
||||
|
||||
/// Prometheus `generateGroupingLabels`; empty values are dropped as absent labels.
|
||||
fn apply(self, input: &MetricName) -> Result<MetricName> {
|
||||
fn apply(self, input: &SeriesLabels) -> Result<SeriesLabels> {
|
||||
let mut metric = input.clone();
|
||||
match self {
|
||||
Self::By(labels) => metric.keep_only(labels),
|
||||
@@ -744,7 +744,7 @@ impl Grouping<'_> {
|
||||
|
||||
type LabelKey = Vec<(Arc<str>, Arc<str>)>;
|
||||
|
||||
fn metric_bytes(metric: &MetricName) -> usize {
|
||||
fn metric_bytes(metric: &SeriesLabels) -> usize {
|
||||
metric
|
||||
.name()
|
||||
.map_or(0, str::len)
|
||||
@@ -761,10 +761,10 @@ fn metric_bytes(metric: &MetricName) -> usize {
|
||||
.len()
|
||||
.saturating_mul(std::mem::size_of::<(Arc<str>, Arc<str>)>()),
|
||||
)
|
||||
.saturating_add(std::mem::size_of::<MetricName>())
|
||||
.saturating_add(std::mem::size_of::<SeriesLabels>())
|
||||
}
|
||||
|
||||
fn grouping_workspace_bytes(metric: &MetricName) -> usize {
|
||||
fn grouping_workspace_bytes(metric: &SeriesLabels) -> usize {
|
||||
metric_bytes(metric)
|
||||
.saturating_add(
|
||||
metric
|
||||
@@ -843,7 +843,7 @@ fn grouping_bytes(grouping: Grouping<'_>) -> usize {
|
||||
.sum::<usize>()
|
||||
}
|
||||
|
||||
fn label_key(metric: &MetricName) -> LabelKey {
|
||||
fn label_key(metric: &SeriesLabels) -> LabelKey {
|
||||
let mut labels = Vec::with_capacity(metric.tags().len() + 1);
|
||||
if let Some(name) = metric.name() {
|
||||
labels.push((Arc::from("__name__"), Arc::from(name)));
|
||||
@@ -862,7 +862,7 @@ fn label_key(metric: &MetricName) -> LabelKey {
|
||||
const BLOCK_POINTS: usize = 64;
|
||||
|
||||
struct Group {
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
/// Keyed by absolute grid index / `BLOCK_POINTS`; each block holds one state per field for
|
||||
/// each of its points, point by point.
|
||||
blocks: BTreeMap<usize, Box<[FloatState]>>,
|
||||
|
||||
@@ -30,7 +30,7 @@ use std::collections::{BTreeMap, HashMap};
|
||||
use std::sync::Arc;
|
||||
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::samples::{SampleRef, Series, SeriesSchema};
|
||||
|
||||
use crate::aggregate::{
|
||||
@@ -85,7 +85,7 @@ pub struct AccumulatorState {
|
||||
/// where no sample of that field was folded in.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PartialGroup {
|
||||
pub metric: MetricName,
|
||||
pub metric: SeriesLabels,
|
||||
pub points: Vec<(usize, Vec<Option<AccumulatorState>>)>,
|
||||
}
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ fn schema_with_grid_len(fields: &[&str], len: u64) -> Arc<SeriesSchema> {
|
||||
})
|
||||
}
|
||||
|
||||
fn metric(name: &str, labels: &[(&str, &str)]) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn metric(name: &str, labels: &[(&str, &str)]) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(name.into()),
|
||||
labels
|
||||
.iter()
|
||||
@@ -81,7 +81,7 @@ fn metric(name: &str, labels: &[(&str, &str)]) -> MetricName {
|
||||
/// Each field is split at a different offset into chunks with nonzero Arrow offsets.
|
||||
fn input(
|
||||
schema: &SeriesSchema,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
start: usize,
|
||||
fields: &[Vec<Option<f64>>],
|
||||
) -> Series {
|
||||
@@ -423,7 +423,7 @@ fn fields_are_aggregated_independently() {
|
||||
.collect();
|
||||
let q = input(
|
||||
&schema(&["scalar"]),
|
||||
MetricName::try_new(None, Vec::new()).unwrap(),
|
||||
SeriesLabels::try_new(None, Vec::new()).unwrap(),
|
||||
0,
|
||||
&[q_values],
|
||||
);
|
||||
@@ -878,7 +878,7 @@ fn grouping_labels_follow_prometheus_and_treat_empty_values_as_absent() {
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let job = MetricName::try_new(None, metric("m", &[("job", "x")]).tags().to_vec()).unwrap();
|
||||
let job = SeriesLabels::try_new(None, metric("m", &[("job", "x")]).tags().to_vec()).unwrap();
|
||||
assert_eq!(
|
||||
labels(Grouping::By(&["host", "job"])),
|
||||
[(job.clone(), vec![Some(3.0)])]
|
||||
@@ -892,13 +892,13 @@ fn grouping_labels_follow_prometheus_and_treat_empty_values_as_absent() {
|
||||
assert_eq!(by_name.len(), 2);
|
||||
assert_eq!(
|
||||
by_name[0].0,
|
||||
MetricName::try_new(Some("a".into()), vec![]).unwrap()
|
||||
SeriesLabels::try_new(Some("a".into()), vec![]).unwrap()
|
||||
);
|
||||
let unnamed = [
|
||||
input(&schema, metric("", &[]), 0, &[vec![Some(1.0)]]),
|
||||
input(
|
||||
&schema,
|
||||
MetricName::try_new(None, vec![]).unwrap(),
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
0,
|
||||
&[vec![Some(2.0)]],
|
||||
),
|
||||
@@ -915,7 +915,10 @@ fn grouping_labels_follow_prometheus_and_treat_empty_values_as_absent() {
|
||||
let none = labels(Grouping::By(&[]));
|
||||
assert_eq!(
|
||||
none,
|
||||
[(MetricName::try_new(None, vec![]).unwrap(), vec![Some(3.0)])]
|
||||
[(
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
vec![Some(3.0)]
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -982,7 +985,7 @@ fn grouping_keeps_type_and_unit_labels() {
|
||||
};
|
||||
assert_eq!(
|
||||
labels(Grouping::Without(&["job"])),
|
||||
MetricName::try_new(
|
||||
SeriesLabels::try_new(
|
||||
None,
|
||||
metric("a", &[("__type__", "gauge"), ("__unit__", "seconds")])
|
||||
.tags()
|
||||
@@ -992,7 +995,7 @@ fn grouping_keeps_type_and_unit_labels() {
|
||||
);
|
||||
assert_eq!(
|
||||
labels(Grouping::By(&["__unit__"])),
|
||||
MetricName::try_new(
|
||||
SeriesLabels::try_new(
|
||||
None,
|
||||
metric("a", &[("__unit__", "seconds")]).tags().to_vec()
|
||||
)
|
||||
@@ -1240,7 +1243,7 @@ fn quantile_without_q_at_a_point_has_no_result() {
|
||||
];
|
||||
let q = input(
|
||||
&schema,
|
||||
MetricName::try_new(None, Vec::new()).unwrap(),
|
||||
SeriesLabels::try_new(None, Vec::new()).unwrap(),
|
||||
10,
|
||||
&[vec![Some(0.5), None, Some(0.5)]],
|
||||
);
|
||||
@@ -1312,7 +1315,7 @@ fn quantile_over_one_point_members_reads_each_member_at_its_point() {
|
||||
.collect();
|
||||
let q = input(
|
||||
&schema,
|
||||
MetricName::try_new(None, Vec::new()).unwrap(),
|
||||
SeriesLabels::try_new(None, Vec::new()).unwrap(),
|
||||
0,
|
||||
&[vec![Some(0.5); 128]],
|
||||
);
|
||||
|
||||
@@ -80,7 +80,7 @@ mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use datatypes::arrow::array::Float64Array;
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::samples::{FieldSpec, Samples, Series, SeriesFields, SeriesSchema};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpec, TimeAxis};
|
||||
|
||||
@@ -97,8 +97,8 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn metric() -> MetricName {
|
||||
MetricName::try_new(Some("requests".into()), Vec::new()).unwrap()
|
||||
fn metric() -> SeriesLabels {
|
||||
SeriesLabels::try_new(Some("requests".into()), Vec::new()).unwrap()
|
||||
}
|
||||
|
||||
/// `values` are the floats this chunk finished evaluating; `start` is their absolute offset.
|
||||
|
||||
@@ -1130,7 +1130,7 @@ fn render_labels(labels: &LabelSet) -> String {
|
||||
/// would miss exactly those collisions.
|
||||
///
|
||||
/// The key is [`crate::grid_series::label_set`]'s normalization of the final labels rather than
|
||||
/// [`datatypes::series::MetricName`] itself: a label with an empty value is no label to
|
||||
/// [`datatypes::series::SeriesLabels`] itself: a label with an empty value is no label to
|
||||
/// Prometheus, so `{host="h", zone=""}` and `{host="h"}` are one label set and have to be compared
|
||||
/// as one. Encoding the tags as they are would file them apart and let one point hold two values.
|
||||
///
|
||||
|
||||
@@ -64,7 +64,7 @@ use datatypes::series::frame::{RawLabelMode, pack_raw_series_chunk, raw_series_f
|
||||
use datatypes::series::raw::{RawSeriesChunk, RawTimestamps};
|
||||
use datatypes::series::samples::{FieldSpec, Samples, Series, SeriesFields, SeriesSchema};
|
||||
use datatypes::series::time::{EvalGrid, GridSpan, GridSpec, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName, SeriesOrdering};
|
||||
use datatypes::series::{Label, SeriesLabels, SeriesOrdering};
|
||||
use futures::{Stream, StreamExt, TryStreamExt};
|
||||
use store_api::region_engine::RawLabelSource;
|
||||
|
||||
@@ -669,7 +669,7 @@ fn no_values(rows: &[(i64, f64)]) -> Vec<Option<f64>> {
|
||||
fn chunk_of(
|
||||
schema: &SeriesSchema,
|
||||
key: &str,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
times: &[i64],
|
||||
values: Vec<Vec<Option<f64>>>,
|
||||
last: bool,
|
||||
@@ -712,8 +712,8 @@ fn series_chunk(host: &str, rows: &[(i64, f64)], last: bool) -> RawSeriesChunk {
|
||||
}
|
||||
|
||||
/// The metric these tests read, with `labels` on it and the name given.
|
||||
fn metric(labels: &[(&str, &str)], name: Option<&str>) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn metric(labels: &[(&str, &str)], name: Option<&str>) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
name.map(Arc::from),
|
||||
labels
|
||||
.iter()
|
||||
@@ -1688,7 +1688,7 @@ fn a_chunk_of_several_runs_converts_its_own_rows_only() {
|
||||
.expect("the spans are increasing and inside the grid");
|
||||
let chunk = EvaluatedChunk::try_new(
|
||||
Series {
|
||||
metric: MetricName::try_new(Some(Arc::from(METRIC)), Vec::new())
|
||||
metric: SeriesLabels::try_new(Some(Arc::from(METRIC)), Vec::new())
|
||||
.expect("one metric name is a legal identity"),
|
||||
time: axis,
|
||||
fields: SeriesFields::try_from_vec(vec![Samples::from_float(Float64Array::from(
|
||||
@@ -2405,7 +2405,7 @@ fn a_claim_compares_label_sets_without_empty_values() {
|
||||
labels.attach(&pool);
|
||||
let axis = TimeAxis::from_grid_spans(Arc::clone(&grid()), vec![GridSpan::new(0, 5)])
|
||||
.expect("one run over the whole grid");
|
||||
let series_of = |metric: MetricName| Series {
|
||||
let series_of = |metric: SeriesLabels| Series {
|
||||
metric,
|
||||
time: axis.clone(),
|
||||
fields: SeriesFields::one(Samples::from_float(Float64Array::from(vec![1.0; 5]))),
|
||||
|
||||
@@ -18,7 +18,7 @@ use datafusion::arrow::array::{ArrayRef, Float64Array, StringArray, TimestampMil
|
||||
use datafusion::arrow::datatypes::{DataType, SchemaRef, TimeUnit};
|
||||
use datafusion::arrow::record_batch::RecordBatch;
|
||||
use datafusion::error::{DataFusionError, Result as DataFusionResult};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::raw::RawTimestamps;
|
||||
use datatypes::series::samples::{SampleRef, Samples, SeriesFields, SeriesSchema};
|
||||
|
||||
@@ -197,7 +197,7 @@ impl NativeInstantMapping {
|
||||
/// Selects instants against typed samples, then maps only selected values to Arrow.
|
||||
pub(crate) fn evaluate(
|
||||
&self,
|
||||
metric: &MetricName,
|
||||
metric: &SeriesLabels,
|
||||
time: &RawTimestamps,
|
||||
fields: &SeriesFields,
|
||||
) -> DataFusionResult<RecordBatch> {
|
||||
|
||||
@@ -29,7 +29,7 @@ use datafusion::logical_expr::{EmptyRelation, LogicalPlan};
|
||||
use datatypes::arrow::buffer::ScalarBuffer;
|
||||
use datatypes::series::raw::{RawSeriesChunk, RawTimestamps};
|
||||
use datatypes::series::samples::{FieldSpec, Samples, SeriesFields, SeriesSchema};
|
||||
use datatypes::series::{MetricName, SeriesOrdering};
|
||||
use datatypes::series::{SeriesLabels, SeriesOrdering};
|
||||
use futures::Stream;
|
||||
use store_api::region_engine::{RawLabelSource, RawSeriesStream, SendableRawSeriesStream};
|
||||
|
||||
@@ -87,7 +87,7 @@ fn chunk(time: &[i64], values: &[f64], last: bool) -> RawSeriesChunk {
|
||||
RawSeriesChunk::try_new(
|
||||
&raw_schema(),
|
||||
datatypes::arrow::buffer::Buffer::from(vec![1, 2, 3]),
|
||||
Some(MetricName::try_new(None, vec![]).unwrap()),
|
||||
Some(SeriesLabels::try_new(None, vec![]).unwrap()),
|
||||
RawTimestamps::try_new(ScalarBuffer::from(time.to_vec())).unwrap(),
|
||||
SeriesFields::one(Samples::from_float(Float64Array::from(values.to_vec()))),
|
||||
last,
|
||||
@@ -263,7 +263,7 @@ fn dropping_pending_stream_releases_source_chunks_and_memory() {
|
||||
let pending_chunk = RawSeriesChunk::try_new(
|
||||
&raw_schema(),
|
||||
datatypes::arrow::buffer::Buffer::from(vec![1]),
|
||||
Some(MetricName::try_new(None, vec![]).unwrap()),
|
||||
Some(SeriesLabels::try_new(None, vec![]).unwrap()),
|
||||
RawTimestamps::try_new(ScalarBuffer::from(vec![10])).unwrap(),
|
||||
SeriesFields::one(samples),
|
||||
false,
|
||||
@@ -344,7 +344,7 @@ fn dense_large_chunk_uses_segment_count_not_row_count_for_descriptors() {
|
||||
let dense_chunk = RawSeriesChunk::try_new(
|
||||
&raw_schema(),
|
||||
datatypes::arrow::buffer::Buffer::from(vec![1]),
|
||||
Some(MetricName::try_new(None, vec![]).unwrap()),
|
||||
Some(SeriesLabels::try_new(None, vec![]).unwrap()),
|
||||
RawTimestamps::try_new(ScalarBuffer::from(timestamps)).unwrap(),
|
||||
SeriesFields::one(Samples::from_float(values)),
|
||||
true,
|
||||
|
||||
@@ -23,7 +23,7 @@ use datafusion::logical_expr::{EmptyRelation, LogicalPlan};
|
||||
use datatypes::arrow::buffer::ScalarBuffer;
|
||||
use datatypes::series::raw::RawTimestamps;
|
||||
use datatypes::series::samples::{FieldSpec, Samples, SeriesFields, SeriesSchema};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -72,7 +72,7 @@ fn series_schema() -> Arc<SeriesSchema> {
|
||||
})
|
||||
}
|
||||
|
||||
fn metric(zone: Option<&str>) -> MetricName {
|
||||
fn metric(zone: Option<&str>) -> SeriesLabels {
|
||||
let labels = zone
|
||||
.map(|value| {
|
||||
vec![Label {
|
||||
@@ -81,7 +81,7 @@ fn metric(zone: Option<&str>) -> MetricName {
|
||||
}]
|
||||
})
|
||||
.unwrap_or_default();
|
||||
MetricName::try_new(None, labels).unwrap()
|
||||
SeriesLabels::try_new(None, labels).unwrap()
|
||||
}
|
||||
|
||||
/// The ordered, deliberately non-lexical field names of the multifloat regression.
|
||||
|
||||
@@ -21,7 +21,7 @@ use datatypes::series::samples::{
|
||||
FieldSpec, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpec, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
|
||||
type Points = Vec<(usize, f64)>;
|
||||
|
||||
@@ -31,7 +31,7 @@ pub(crate) struct Case {
|
||||
pub(crate) schema: Arc<SeriesSchema>,
|
||||
pub(crate) series: Vec<Series>,
|
||||
pub(crate) scalar: Option<Series>,
|
||||
pub(crate) result: Vec<(MetricName, Points)>,
|
||||
pub(crate) result: Vec<(SeriesLabels, Points)>,
|
||||
}
|
||||
|
||||
/// Parses a fixture of `case`/`expr`/`grid`/`series`/`scalar`/`result`/`end` blocks.
|
||||
@@ -94,7 +94,7 @@ pub(crate) fn cases(text: &str) -> Vec<Case> {
|
||||
cases
|
||||
}
|
||||
|
||||
fn parse_metric(labels: &str) -> MetricName {
|
||||
fn parse_metric(labels: &str) -> SeriesLabels {
|
||||
let mut name = None;
|
||||
let mut tags = Vec::new();
|
||||
for label in labels
|
||||
@@ -111,7 +111,7 @@ fn parse_metric(labels: &str) -> MetricName {
|
||||
});
|
||||
}
|
||||
}
|
||||
MetricName::try_new(name, tags).unwrap()
|
||||
SeriesLabels::try_new(name, tags).unwrap()
|
||||
}
|
||||
|
||||
fn parse_points(points: &str) -> Points {
|
||||
@@ -132,7 +132,7 @@ pub(crate) fn hex(bits: &str) -> f64 {
|
||||
}
|
||||
|
||||
/// Builds the trimmed series Eval produces: from the first to the last point, nulls between.
|
||||
fn grid_series(schema: &SeriesSchema, metric: MetricName, points: &Points) -> Option<Series> {
|
||||
fn grid_series(schema: &SeriesSchema, metric: SeriesLabels, points: &Points) -> Option<Series> {
|
||||
let (&(start, _), &(last, _)) = points.first().zip(points.last())?;
|
||||
let mut values = vec![None; last - start + 1];
|
||||
for &(index, value) in points {
|
||||
@@ -329,7 +329,7 @@ pub(crate) fn close(a: f64, b: f64) -> bool {
|
||||
/// A label set as name/value pairs, the way the fixtures name one.
|
||||
type LabelKey = Vec<(String, String)>;
|
||||
|
||||
fn label_key(metric: &MetricName) -> LabelKey {
|
||||
fn label_key(metric: &SeriesLabels) -> LabelKey {
|
||||
let mut key = metric
|
||||
.tags()
|
||||
.iter()
|
||||
|
||||
@@ -21,7 +21,7 @@ use std::sync::Arc;
|
||||
use datafusion::arrow::array::builder::NullBufferBuilder;
|
||||
use datafusion::arrow::array::{Array, Float64Array, UInt32Array};
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::histogram::{HistogramBatch, HistogramBatchBuilder};
|
||||
use datatypes::series::samples::{
|
||||
DenseSamplesRef, HistogramSamples, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
@@ -312,7 +312,7 @@ impl GridSeriesBuilder {
|
||||
///
|
||||
/// Nothing is reset: not the metric, not the index cursor, not the position order. A caller
|
||||
/// that wants a new series calls [`Self::begin_series`].
|
||||
pub fn take_buffered(&mut self, metric: MetricName) -> Result<Option<Series>> {
|
||||
pub fn take_buffered(&mut self, metric: SeriesLabels) -> Result<Option<Series>> {
|
||||
self.collect(metric)
|
||||
}
|
||||
|
||||
@@ -322,12 +322,12 @@ impl GridSeriesBuilder {
|
||||
/// The rows share the one buffer per field, so the result costs a span per run and not a row
|
||||
/// per position between the runs. This ends the logical series; the next one starts with
|
||||
/// [`Self::begin_series`], which is the only reset.
|
||||
pub fn finish(&mut self, metric: MetricName) -> Result<Option<Series>> {
|
||||
pub fn finish(&mut self, metric: SeriesLabels) -> Result<Option<Series>> {
|
||||
self.collect(metric)
|
||||
}
|
||||
|
||||
/// Turns the buffered rows into one series over the runs they make up.
|
||||
fn collect(&mut self, metric: MetricName) -> Result<Option<Series>> {
|
||||
fn collect(&mut self, metric: SeriesLabels) -> Result<Option<Series>> {
|
||||
if self.indices.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
@@ -421,7 +421,7 @@ pub(crate) fn render_label_set(labels: &LabelSet) -> String {
|
||||
}
|
||||
|
||||
/// The label set Prometheus compares, which has no empty values.
|
||||
pub(crate) fn label_set(metric: &MetricName) -> LabelSet {
|
||||
pub(crate) fn label_set(metric: &SeriesLabels) -> LabelSet {
|
||||
let name = metric
|
||||
.name()
|
||||
.filter(|name| !name.is_empty())
|
||||
|
||||
@@ -26,7 +26,7 @@ use datatypes::series::samples::{
|
||||
HistogramSamples, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpan, GridSpec, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
use rand::Rng;
|
||||
|
||||
use crate::histogram_eval::float_histogram::FloatHistogram;
|
||||
@@ -62,7 +62,7 @@ pub(crate) fn expand(series: &Series) -> Dense {
|
||||
}
|
||||
|
||||
/// Asserts `actual` is the trimmed form of `expected`, with identical value bits and metric.
|
||||
pub(crate) fn assert_series_eq(actual: Option<&Series>, expected: &Dense, metric: &MetricName) {
|
||||
pub(crate) fn assert_series_eq(actual: Option<&Series>, expected: &Dense, metric: &SeriesLabels) {
|
||||
assert_series_matches(actual, expected, metric, f64::to_bits, "");
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ pub(crate) fn assert_series_eq(actual: Option<&Series>, expected: &Dense, metric
|
||||
pub(crate) fn assert_series_eq_any_nan(
|
||||
actual: Option<&Series>,
|
||||
expected: &Dense,
|
||||
metric: &MetricName,
|
||||
metric: &SeriesLabels,
|
||||
context: &str,
|
||||
) {
|
||||
let any_nan = |value: f64| {
|
||||
@@ -88,7 +88,7 @@ pub(crate) fn assert_series_eq_any_nan(
|
||||
fn assert_series_matches(
|
||||
actual: Option<&Series>,
|
||||
expected: &Dense,
|
||||
metric: &MetricName,
|
||||
metric: &SeriesLabels,
|
||||
bits_of: fn(f64) -> u64,
|
||||
context: &str,
|
||||
) {
|
||||
@@ -199,7 +199,7 @@ pub(crate) fn piece_ranges(pieces: &[Series]) -> Vec<(usize, usize)> {
|
||||
/// A result carries only the positions that hold a value, so its rows may form several runs: the
|
||||
/// comparison expands it over the grid and checks it covers exactly the valued positions. `None`
|
||||
/// means no row survived, which is only right when `expected` holds no value either.
|
||||
pub(crate) fn assert_result_eq(actual: Option<&Series>, expected: &Dense, metric: &MetricName) {
|
||||
pub(crate) fn assert_result_eq(actual: Option<&Series>, expected: &Dense, metric: &SeriesLabels) {
|
||||
match actual {
|
||||
Some(actual) => assert_pieces_eq(std::slice::from_ref(actual), expected, metric),
|
||||
None => assert_pieces_eq(&[], expected, metric),
|
||||
@@ -208,7 +208,7 @@ pub(crate) fn assert_result_eq(actual: Option<&Series>, expected: &Dense, metric
|
||||
|
||||
/// Asserts `pieces` are the pieces of `expected`: they reproduce it, and together they cover
|
||||
/// exactly the positions that hold a value, none of them twice.
|
||||
pub(crate) fn assert_pieces_eq(pieces: &[Series], expected: &Dense, metric: &MetricName) {
|
||||
pub(crate) fn assert_pieces_eq(pieces: &[Series], expected: &Dense, metric: &SeriesLabels) {
|
||||
for piece in pieces {
|
||||
assert_eq!(&piece.metric, metric, "a piece changed the metric");
|
||||
}
|
||||
@@ -386,10 +386,10 @@ pub(crate) fn golden_cases(text: &str) -> Vec<GoldenCase> {
|
||||
cases
|
||||
}
|
||||
|
||||
pub(crate) fn metric_of(labels: &Labels) -> MetricName {
|
||||
pub(crate) fn metric_of(labels: &Labels) -> SeriesLabels {
|
||||
let mut labels = labels.clone();
|
||||
let name = labels.remove("__name__").map(Arc::from);
|
||||
MetricName::try_new(
|
||||
SeriesLabels::try_new(
|
||||
name,
|
||||
labels
|
||||
.into_iter()
|
||||
@@ -402,7 +402,7 @@ pub(crate) fn metric_of(labels: &Labels) -> MetricName {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn labels_of(metric: &MetricName) -> Labels {
|
||||
pub(crate) fn labels_of(metric: &SeriesLabels) -> Labels {
|
||||
let mut labels: Labels = metric
|
||||
.tags()
|
||||
.iter()
|
||||
|
||||
@@ -22,7 +22,7 @@ use datatypes::series::samples::{
|
||||
SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridSpan, GridSpec, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
use rand::rngs::StdRng;
|
||||
use rand::{Rng, SeedableRng};
|
||||
|
||||
@@ -47,8 +47,8 @@ fn grid_schema(fields: usize, grid_len: u64) -> Arc<SeriesSchema> {
|
||||
})
|
||||
}
|
||||
|
||||
fn metric(host: usize) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn metric(host: usize) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(Arc::from("cpu")),
|
||||
vec![Label {
|
||||
name: Arc::from("host"),
|
||||
|
||||
@@ -32,7 +32,7 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::histogram::HistogramView;
|
||||
use datatypes::series::samples::{DenseSamplesRef, RowCursor, SampleRef, Series, SeriesSchema};
|
||||
use datatypes::series::time::{TimeAxis, union_positions};
|
||||
@@ -101,7 +101,7 @@ pub fn evaluate_histograms(
|
||||
// run, as `merge_same_labelset` keeps it.
|
||||
let mut index: HashMap<LabelSet, usize> = HashMap::new();
|
||||
let mut groups: Vec<Group<'_>> = Vec::new();
|
||||
let mut group_of = |metric: MetricName| {
|
||||
let mut group_of = |metric: SeriesLabels| {
|
||||
*index.entry(label_set(&metric)).or_insert_with(|| {
|
||||
groups.push(Group::new(metric));
|
||||
groups.len() - 1
|
||||
@@ -231,13 +231,13 @@ pub fn evaluate_histograms(
|
||||
/// The series of one label set (`le` aside): classic buckets, and the series of exactly that
|
||||
/// label set when it holds native histograms.
|
||||
struct Group<'a> {
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
classic: Vec<(f64, &'a Series)>,
|
||||
native: Option<&'a Series>,
|
||||
}
|
||||
|
||||
impl Group<'_> {
|
||||
fn new(metric: MetricName) -> Self {
|
||||
fn new(metric: SeriesLabels) -> Self {
|
||||
Self {
|
||||
metric,
|
||||
classic: Vec::new(),
|
||||
|
||||
@@ -19,7 +19,7 @@ use std::sync::Arc;
|
||||
|
||||
use datafusion::arrow::array::UInt32Array;
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::histogram::HistogramBatchBuilder;
|
||||
use datatypes::series::samples::{
|
||||
RowCursor, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
@@ -45,7 +45,7 @@ pub fn aggregate_histograms(
|
||||
op: HistogramAggregate,
|
||||
schema: &Arc<SeriesSchema>,
|
||||
group: &[Series],
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
) -> Result<Option<Series>> {
|
||||
let grid = schema.eval_grid.clone().ok_or_else(|| {
|
||||
DataFusionError::Execution("histogram aggregation requires an evaluation grid".into())
|
||||
|
||||
@@ -29,7 +29,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap};
|
||||
use std::sync::Arc;
|
||||
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::samples::{SampleRef, Series, SeriesSchema};
|
||||
use regex::Regex;
|
||||
|
||||
@@ -187,7 +187,7 @@ pub fn info(
|
||||
|
||||
let width = schema.fields.len();
|
||||
let mut result_index: HashMap<LabelSet, usize> = HashMap::new();
|
||||
let mut results: Vec<(MetricName, Vec<Row>)> = Vec::new();
|
||||
let mut results: Vec<(SeriesLabels, Vec<Row>)> = Vec::new();
|
||||
let mut added: Vec<(Arc<str>, Arc<str>)> = Vec::new();
|
||||
let mut chosen: Vec<usize> = Vec::new();
|
||||
for series in base {
|
||||
@@ -346,7 +346,7 @@ impl FirstError {
|
||||
type Signature = (Arc<str>, Vec<Option<Arc<str>>>);
|
||||
|
||||
/// The value of each identifying label, `None` where the series does not have it.
|
||||
fn identifying_values(metric: &MetricName) -> Vec<Option<Arc<str>>> {
|
||||
fn identifying_values(metric: &SeriesLabels) -> Vec<Option<Arc<str>>> {
|
||||
IDENTIFYING_LABELS
|
||||
.iter()
|
||||
.map(|label| {
|
||||
@@ -361,8 +361,8 @@ fn identifying_values(metric: &MetricName) -> Vec<Option<Arc<str>>> {
|
||||
/// Adds the data labels `info` gives a series with labels `base` to `added`; returns the name of
|
||||
/// a label another info metric already set to a different value.
|
||||
fn add_data_labels(
|
||||
info: &MetricName,
|
||||
base: &MetricName,
|
||||
info: &SeriesLabels,
|
||||
base: &SeriesLabels,
|
||||
selector: &InfoSelector,
|
||||
added: &mut Vec<(Arc<str>, Arc<str>)>,
|
||||
) -> std::result::Result<(), Arc<str>> {
|
||||
|
||||
@@ -17,7 +17,7 @@ use std::sync::Arc;
|
||||
|
||||
use common_query::prometheus::is_prometheus_stale_nan;
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::raw::RawTimestamps;
|
||||
use datatypes::series::samples::{SampleRef, Series, SeriesFields, SeriesSchema};
|
||||
|
||||
@@ -162,7 +162,7 @@ pub fn select_instants(
|
||||
/// ignores an offset next to `@` here, while `info()` applies it.
|
||||
pub fn timestamp_of_selection(
|
||||
schema: &Arc<SeriesSchema>,
|
||||
metric: &MetricName,
|
||||
metric: &SeriesLabels,
|
||||
time: &RawTimestamps,
|
||||
fields: &SeriesFields,
|
||||
indices: &[u64],
|
||||
@@ -186,7 +186,7 @@ pub fn timestamp_of_selection(
|
||||
/// Takes the same selection as [`timestamp_of_selection`].
|
||||
pub fn info_sample_times(
|
||||
schema: &Arc<SeriesSchema>,
|
||||
metric: &MetricName,
|
||||
metric: &SeriesLabels,
|
||||
time: &RawTimestamps,
|
||||
fields: &SeriesFields,
|
||||
indices: &[u64],
|
||||
@@ -254,7 +254,7 @@ pub fn timestamp_of_evaluated(
|
||||
/// have fails.
|
||||
fn project_selection(
|
||||
schema: &Arc<SeriesSchema>,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
time: &RawTimestamps,
|
||||
fields: &SeriesFields,
|
||||
indices: &[u64],
|
||||
|
||||
@@ -35,7 +35,7 @@ use std::sync::Arc;
|
||||
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::arrow::array::Float64Array;
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::samples::{
|
||||
DenseSamplesRef, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
};
|
||||
@@ -201,7 +201,7 @@ pub fn constant_series(schema: &SeriesSchema, range: GridRange, scalar: f64) ->
|
||||
])));
|
||||
Series::try_new(
|
||||
schema,
|
||||
MetricName::try_new(None, vec![]).map_err(series_error)?,
|
||||
SeriesLabels::try_new(None, vec![]).map_err(series_error)?,
|
||||
TimeAxis::Grid(range),
|
||||
fields,
|
||||
)
|
||||
@@ -232,31 +232,31 @@ fn map_float_fields(
|
||||
/// Prometheus `DropReserved(schema.IsMetadataLabel)` drops the type and unit labels with the
|
||||
/// name. Empty values are dropped too: Prometheus has no empty labels, and keeping them would
|
||||
/// hide a same-labelset collision from the caller.
|
||||
pub(crate) fn drop_metric_name(metric: &MetricName) -> Result<MetricName> {
|
||||
pub(crate) fn drop_metric_name(metric: &SeriesLabels) -> Result<SeriesLabels> {
|
||||
rebuild_labels(metric, None, |name| {
|
||||
!matches!(name, "__type__" | "__unit__")
|
||||
})
|
||||
}
|
||||
|
||||
/// Drops labels with empty values, which Prometheus treats as absent.
|
||||
pub(crate) fn drop_empty_labels(metric: &MetricName) -> Result<MetricName> {
|
||||
pub(crate) fn drop_empty_labels(metric: &SeriesLabels) -> Result<SeriesLabels> {
|
||||
let name = metric.name().filter(|name| !name.is_empty()).map(Arc::from);
|
||||
rebuild_labels(metric, name, |_| true)
|
||||
}
|
||||
|
||||
/// One rebuild: removing labels one by one copies the label array each time.
|
||||
fn rebuild_labels(
|
||||
metric: &MetricName,
|
||||
metric: &SeriesLabels,
|
||||
name: Option<Arc<str>>,
|
||||
keep: impl Fn(&str) -> bool,
|
||||
) -> Result<MetricName> {
|
||||
) -> Result<SeriesLabels> {
|
||||
let tags = metric
|
||||
.tags()
|
||||
.iter()
|
||||
.filter(|label| !label.value.is_empty() && keep(&label.name))
|
||||
.cloned()
|
||||
.collect();
|
||||
MetricName::try_new(name, tags).map_err(series_error)
|
||||
SeriesLabels::try_new(name, tags).map_err(series_error)
|
||||
}
|
||||
|
||||
impl MathOp {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::samples::{FieldSpec, SampleRef, Series, SeriesSchema};
|
||||
use datatypes::series::time::TimeAxis;
|
||||
|
||||
@@ -226,7 +226,7 @@ fn map_grid_scalar(
|
||||
schema: &Arc<SeriesSchema>,
|
||||
vector: &Series,
|
||||
scalar: ScalarSeriesOperand<'_>,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
calculate: impl Fn(f64, f64, f64) -> Option<f64>,
|
||||
) -> Result<Option<Series>> {
|
||||
let vector_time = validate_float_series(schema, vector)?;
|
||||
|
||||
@@ -32,7 +32,7 @@ use datatypes::series::histogram::{
|
||||
};
|
||||
use datatypes::series::samples::{FieldSpec, HistogramSamples, SampleRef};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpan, GridSpec};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
|
||||
use super::*;
|
||||
use crate::functions::IeeeSqrt;
|
||||
@@ -55,7 +55,7 @@ fn series(schema: &SeriesSchema, start: usize, fields: Vec<Samples>) -> Series {
|
||||
let time = TimeAxis::Grid(
|
||||
GridRange::try_new(schema.eval_grid.clone().unwrap(), start, fields[0].len()).unwrap(),
|
||||
);
|
||||
let metric = MetricName::try_new(
|
||||
let metric = SeriesLabels::try_new(
|
||||
Some("requests".into()),
|
||||
vec![
|
||||
Label {
|
||||
@@ -604,7 +604,7 @@ fn scalar_functions_pair_scalars_by_position() {
|
||||
let scalar = |start: usize, values: &[Option<f64>]| {
|
||||
Series::try_new(
|
||||
&schema,
|
||||
MetricName::try_new(None, Vec::new()).unwrap(),
|
||||
SeriesLabels::try_new(None, Vec::new()).unwrap(),
|
||||
TimeAxis::Grid(
|
||||
GridRange::try_new(schema.eval_grid.clone().unwrap(), start, values.len()).unwrap(),
|
||||
),
|
||||
|
||||
@@ -24,7 +24,7 @@ fn scalar(schema: &SeriesSchema, start: usize, samples: Samples) -> Series {
|
||||
};
|
||||
Series::try_new(
|
||||
&scalar_schema,
|
||||
MetricName::try_new(None, vec![]).unwrap(),
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
TimeAxis::Grid(
|
||||
GridRange::try_new(schema.eval_grid.clone().unwrap(), start, samples.len()).unwrap(),
|
||||
),
|
||||
@@ -559,7 +559,7 @@ fn parameters_are_read_per_point_and_missing_ones_drop_the_point() {
|
||||
.into(),
|
||||
eval_grid: schema.eval_grid.clone(),
|
||||
},
|
||||
MetricName::try_new(None, vec![]).unwrap(),
|
||||
SeriesLabels::try_new(None, vec![]).unwrap(),
|
||||
TimeAxis::from_grid_spans(
|
||||
schema.eval_grid.clone().unwrap(),
|
||||
vec![GridSpan::new(2, 2), GridSpan::new(5, 1)],
|
||||
|
||||
@@ -347,7 +347,7 @@ fn a_bool_comparison_keeps_the_axis_of_a_sparse_input() {
|
||||
crate::grid_series::reference::assert_result_eq(
|
||||
Some(&output),
|
||||
&expected,
|
||||
&MetricName::try_new(
|
||||
&SeriesLabels::try_new(
|
||||
None,
|
||||
vec![Label {
|
||||
name: "host".into(),
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
use std::sync::{Arc, LazyLock};
|
||||
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::samples::{Series, SeriesSchema};
|
||||
use regex::Regex;
|
||||
|
||||
@@ -146,7 +146,7 @@ pub fn label_join(
|
||||
}
|
||||
|
||||
/// An empty value removes the label, as Prometheus label sets have no empty values.
|
||||
fn set_label(metric: &mut MetricName, name: &str, value: &str) -> Result<()> {
|
||||
fn set_label(metric: &mut SeriesLabels, name: &str, value: &str) -> Result<()> {
|
||||
if value.is_empty() {
|
||||
metric.remove(name);
|
||||
return Ok(());
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
use datafusion::arrow::array::Float64Array;
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::samples::{Samples, Series, SeriesFields, SeriesSchema};
|
||||
use datatypes::series::time::{GridRange, TimeAxis};
|
||||
|
||||
@@ -96,7 +96,7 @@ fn eval_time_series(schema: &SeriesSchema, value: impl Fn(i64) -> f64) -> Result
|
||||
let fields = vec![Samples::from_float(values); schema.fields.len()];
|
||||
Series::try_new(
|
||||
schema,
|
||||
MetricName::try_new(None, Vec::new()).map_err(external)?,
|
||||
SeriesLabels::try_new(None, Vec::new()).map_err(external)?,
|
||||
TimeAxis::Grid(range),
|
||||
SeriesFields::try_from_vec(fields).map_err(external)?,
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ use std::fmt::{self, Write};
|
||||
use std::sync::Arc;
|
||||
|
||||
use datatypes::series::time::EvalGrid;
|
||||
use datatypes::series::{MetricName, SeriesOrdering};
|
||||
use datatypes::series::{SeriesLabels, SeriesOrdering};
|
||||
|
||||
use crate::histogram_eval::HistogramFunction;
|
||||
use crate::map::MathOp;
|
||||
@@ -296,7 +296,7 @@ fn binary_op(op: BinaryOp) -> &'static str {
|
||||
}
|
||||
|
||||
/// The labels of `metric` as `name="value"` pairs, the metric name first.
|
||||
fn label_pairs(metric: &MetricName) -> String {
|
||||
fn label_pairs(metric: &SeriesLabels) -> String {
|
||||
metric
|
||||
.name()
|
||||
.map(|name| format!("__name__={name:?}"))
|
||||
|
||||
@@ -16,7 +16,7 @@ use std::sync::Arc;
|
||||
|
||||
use datatypes::series::samples::{FieldSpec, SeriesSchema};
|
||||
use datatypes::series::time::{EvalGrid, GridSpec};
|
||||
use datatypes::series::{Label, MetricName, SeriesOrdering};
|
||||
use datatypes::series::{Label, SeriesLabels, SeriesOrdering};
|
||||
|
||||
use super::super::plan::{
|
||||
AggregateKind, AggregateStage, BoundAggregate, BoundInput, BoundInstant, BoundMap, BoundScalar,
|
||||
@@ -434,7 +434,7 @@ fn a_vector_operation_names_its_binding() {
|
||||
),
|
||||
(
|
||||
BoundVectorOp::Absent {
|
||||
labels: MetricName::try_new(
|
||||
labels: SeriesLabels::try_new(
|
||||
None,
|
||||
vec![Label {
|
||||
name: "job".into(),
|
||||
|
||||
@@ -99,7 +99,7 @@ use datatypes::series::samples::{
|
||||
DenseSamplesRef, RowCursor, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpan, GridSpec, TimeAxis};
|
||||
use datatypes::series::{MetricName, SeriesOrdering};
|
||||
use datatypes::series::{SeriesLabels, SeriesOrdering};
|
||||
|
||||
use crate::aggregate;
|
||||
use crate::grid_series::{
|
||||
@@ -394,7 +394,7 @@ struct NodeSpec {
|
||||
/// belongs to it and still moves forward.
|
||||
struct OpenSeries {
|
||||
/// The identity of the open series, as the chunk that opened it named it.
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
/// The last absolute position the open series decided, when it decided any.
|
||||
last_position: Option<usize>,
|
||||
}
|
||||
@@ -646,7 +646,7 @@ fn label_bytes(labels: &LabelSet) -> usize {
|
||||
///
|
||||
/// This is the convention [`label_bytes`] keeps: the payload of the shared strings and one row per
|
||||
/// label.
|
||||
fn metric_bytes(metric: &MetricName) -> usize {
|
||||
fn metric_bytes(metric: &SeriesLabels) -> usize {
|
||||
metric.name().map_or(0, |name| name.len())
|
||||
+ std::mem::size_of_val(metric.tags())
|
||||
+ metric
|
||||
@@ -1131,7 +1131,7 @@ struct RetainedInput {
|
||||
/// set may be closed more than once -- a node that rewrites labels can make two series one --
|
||||
/// so a chunk that starts a series again is not an error, only one that starts it before the
|
||||
/// series already open ended, or names another series while it is open.
|
||||
open: Option<(MetricName, usize)>,
|
||||
open: Option<(SeriesLabels, usize)>,
|
||||
/// The chunks this operand handed over, in arrival order.
|
||||
series: Vec<Series>,
|
||||
/// The chunk count at which each logical series closed, exclusive, in arrival order.
|
||||
@@ -1920,7 +1920,7 @@ impl BroadcastRuntime {
|
||||
///
|
||||
/// It is what a series closes under when the operation emptied every position: the labels say
|
||||
/// which series closed, and they are the labels the operation produces, not the ones it read.
|
||||
fn output_metric(&self, metric: &MetricName) -> Result<MetricName> {
|
||||
fn output_metric(&self, metric: &SeriesLabels) -> Result<SeriesLabels> {
|
||||
if self.drops_labels() {
|
||||
drop_metric_name(metric)
|
||||
} else {
|
||||
@@ -2083,7 +2083,7 @@ fn grid_position(grid: &EvalGrid, timestamp: i64) -> Result<usize> {
|
||||
/// A series whose selection picked no source row still closes exactly once, on a chunk that holds
|
||||
/// nothing: the labels say which series closed, and the address says it closed before its first
|
||||
/// point, as the empty chunk a window hands out for such a series does.
|
||||
fn no_row_chunk(schema: &SeriesSchema, metric: MetricName) -> Result<EvaluatedChunk> {
|
||||
fn no_row_chunk(schema: &SeriesSchema, metric: SeriesLabels) -> Result<EvaluatedChunk> {
|
||||
let grid = schema.eval_grid.clone().ok_or_else(|| {
|
||||
DataFusionError::Execution(
|
||||
"an instant selection produces an evaluated chunk, which is addressed on a grid"
|
||||
@@ -4212,7 +4212,7 @@ fn map_chunk(
|
||||
/// series closed, and the axis is empty because no position holds a value. `metric` is the identity
|
||||
/// the operation produces — a map drops the name, a filtering comparison keeps it — so the caller
|
||||
/// says which, rather than this function deciding for it.
|
||||
fn no_row_series(schema: &SeriesSchema, series: &Series, metric: MetricName) -> Result<Series> {
|
||||
fn no_row_series(schema: &SeriesSchema, series: &Series, metric: SeriesLabels) -> Result<Series> {
|
||||
let grid = series.time.grid().ok_or_else(|| {
|
||||
DataFusionError::Execution("a mapped chunk must be addressed on a grid".to_string())
|
||||
})?;
|
||||
|
||||
@@ -31,7 +31,7 @@ use datatypes::series::samples::{
|
||||
DenseSamplesRef, FieldSpec, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpan, GridSpec, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName, SeriesOrdering};
|
||||
use datatypes::series::{Label, SeriesLabels, SeriesOrdering};
|
||||
|
||||
use super::{
|
||||
BinaryRuntime, Emitted, NativeChunk, NativeExecutionState, NativeExecutor, NodeBuffer,
|
||||
@@ -95,8 +95,8 @@ fn evaluated(grid: Arc<EvalGrid>) -> NativeType {
|
||||
NativeType::Samples(evaluated_schema(grid))
|
||||
}
|
||||
|
||||
fn metric() -> MetricName {
|
||||
MetricName::try_new(Some("requests".into()), Vec::new()).unwrap()
|
||||
fn metric() -> SeriesLabels {
|
||||
SeriesLabels::try_new(Some("requests".into()), Vec::new()).unwrap()
|
||||
}
|
||||
|
||||
/// The raw source every supported tree starts from.
|
||||
@@ -270,7 +270,7 @@ fn raw_chunk(
|
||||
fn raw_chunk_of(
|
||||
schema: &SeriesSchema,
|
||||
key: &[u8],
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
timestamps: &[i64],
|
||||
values: &[f64],
|
||||
is_last: bool,
|
||||
@@ -569,7 +569,7 @@ fn evaluated_chunk(
|
||||
/// evaluated result carries where it had nothing to report.
|
||||
fn evaluated_chunk_of(
|
||||
schema: &SeriesSchema,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
start: usize,
|
||||
values: Vec<Option<f64>>,
|
||||
is_last: bool,
|
||||
@@ -583,7 +583,7 @@ fn evaluated_chunk_of(
|
||||
/// Arrow allocation, which is what a source handing over the chunks of one batch does.
|
||||
fn evaluated_array_chunk_of(
|
||||
schema: &SeriesSchema,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
start: usize,
|
||||
values: Float64Array,
|
||||
is_last: bool,
|
||||
@@ -606,7 +606,7 @@ fn evaluated_array_chunk_of(
|
||||
/// same shape hold two allocations of the same size.
|
||||
fn evaluated_histogram_chunk_of(
|
||||
schema: &SeriesSchema,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
start: usize,
|
||||
indices: Vec<Option<u32>>,
|
||||
table: &Arc<HistogramBatch>,
|
||||
@@ -642,8 +642,8 @@ fn histogram_table_bytes(table: &Arc<HistogramBatch>) -> usize {
|
||||
}
|
||||
|
||||
/// The series `name{job="job"}`, so two series can share the label a map leaves behind.
|
||||
fn named_metric(name: &str, job: &str) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn named_metric(name: &str, job: &str) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(name.into()),
|
||||
vec![Label {
|
||||
name: "job".into(),
|
||||
@@ -657,7 +657,7 @@ fn named_metric(name: &str, job: &str) -> MetricName {
|
||||
///
|
||||
/// The two are distinct series to a scan — an empty tag value is a present label, an absent one is
|
||||
/// not — and the same label set to everything that drops empty-valued labels, as Prometheus does.
|
||||
fn host_metric(zone: Option<&str>) -> MetricName {
|
||||
fn host_metric(zone: Option<&str>) -> SeriesLabels {
|
||||
let mut tags = vec![Label {
|
||||
name: "host".into(),
|
||||
value: "web-1".into(),
|
||||
@@ -668,7 +668,7 @@ fn host_metric(zone: Option<&str>) -> MetricName {
|
||||
value: zone.into(),
|
||||
});
|
||||
}
|
||||
MetricName::try_new(Some("requests".into()), tags).unwrap()
|
||||
SeriesLabels::try_new(Some("requests".into()), tags).unwrap()
|
||||
}
|
||||
|
||||
fn pool() -> Arc<dyn MemoryPool> {
|
||||
@@ -2126,7 +2126,7 @@ fn two_series_onto_one_label_set_after_a_window_are_rejected() {
|
||||
.push_raw(raw_chunk_of(
|
||||
&schema,
|
||||
b"series-b",
|
||||
MetricName::try_new(
|
||||
SeriesLabels::try_new(
|
||||
Some("requests".into()),
|
||||
vec![Label {
|
||||
name: "host".into(),
|
||||
@@ -2917,7 +2917,7 @@ fn two_series_with_no_result_do_not_collide() {
|
||||
.push_raw(raw_chunk_of(
|
||||
&schema,
|
||||
name.as_bytes(),
|
||||
MetricName::try_new(Some(name.into()), vec![]).unwrap(),
|
||||
SeriesLabels::try_new(Some(name.into()), vec![]).unwrap(),
|
||||
&[0],
|
||||
&[1.0],
|
||||
true,
|
||||
@@ -2945,7 +2945,7 @@ fn two_series_with_no_result_do_not_collide() {
|
||||
/// positions the chunk does not hold.
|
||||
fn sparse_chunk(
|
||||
schema: &SeriesSchema,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
spans: &[(usize, usize)],
|
||||
values: Vec<f64>,
|
||||
is_last: bool,
|
||||
@@ -4207,7 +4207,7 @@ fn evaluated_input_of(count: usize, grid: Arc<EvalGrid>) -> NativeNode {
|
||||
/// One evaluated chunk of `metric` whose fields carry `columns`, one column per field.
|
||||
fn evaluated_columns(
|
||||
schema: &SeriesSchema,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
start: usize,
|
||||
columns: Vec<Vec<Option<f64>>>,
|
||||
is_last: bool,
|
||||
@@ -4223,7 +4223,7 @@ fn evaluated_columns(
|
||||
/// on its way in.
|
||||
fn evaluated_on(
|
||||
schema: &SeriesSchema,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
start: usize,
|
||||
rows: usize,
|
||||
columns: Vec<Vec<Option<f64>>>,
|
||||
@@ -4252,7 +4252,7 @@ fn evaluated_on(
|
||||
/// `len` positions from `start`.
|
||||
fn evaluated_histograms(
|
||||
schema: &SeriesSchema,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
start: usize,
|
||||
buckets: i32,
|
||||
len: usize,
|
||||
@@ -4292,8 +4292,8 @@ fn histogram_counts(chunk: &EvaluatedChunk) -> Vec<f64> {
|
||||
}
|
||||
|
||||
/// A source bound in label mode: `name{job="api",pod="a"}` and the other series here.
|
||||
fn pod_metric(name: &str, job: &str, pod: &str) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn pod_metric(name: &str, job: &str, pod: &str) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(name.into()),
|
||||
vec![
|
||||
Label {
|
||||
@@ -4310,8 +4310,8 @@ fn pod_metric(name: &str, job: &str, pod: &str) -> MetricName {
|
||||
}
|
||||
|
||||
/// The one side of a `group_left` match: `one{job=...,instance=...}`.
|
||||
fn one_metric(job: &str, instance: &str) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn one_metric(job: &str, instance: &str) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some("one".into()),
|
||||
vec![
|
||||
Label {
|
||||
@@ -6581,8 +6581,8 @@ fn sum_grouping(group: Grouping) -> BoundAggregate {
|
||||
}
|
||||
|
||||
/// `name{job=...,instance=...}`, the two labels these tests group by.
|
||||
fn job_instance_metric(name: &str, job: &str, instance: &str) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn job_instance_metric(name: &str, job: &str, instance: &str) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(name.into()),
|
||||
vec![
|
||||
Label {
|
||||
@@ -7534,7 +7534,7 @@ fn a_broadcast_refuses_two_series_that_share_a_label_set_and_releases_the_reserv
|
||||
let pool = pool();
|
||||
let mut execution = executor(&tree, Arc::clone(&pool), &ExecutionPlanMetricsSet::new());
|
||||
let first_metric =
|
||||
MetricName::try_new(Some("requests".to_string().into()), Vec::new()).unwrap();
|
||||
SeriesLabels::try_new(Some("requests".to_string().into()), Vec::new()).unwrap();
|
||||
execution
|
||||
.push_evaluated(evaluated_chunk_of(
|
||||
&schema,
|
||||
@@ -7554,7 +7554,7 @@ fn a_broadcast_refuses_two_series_that_share_a_label_set_and_releases_the_reserv
|
||||
);
|
||||
|
||||
let second_metric =
|
||||
MetricName::try_new(Some("requests_total".to_string().into()), Vec::new()).unwrap();
|
||||
SeriesLabels::try_new(Some("requests_total".to_string().into()), Vec::new()).unwrap();
|
||||
execution
|
||||
.push_evaluated(evaluated_chunk_of(
|
||||
&schema,
|
||||
@@ -8172,7 +8172,7 @@ fn absent_answers_where_the_input_holds_nothing() {
|
||||
let grid = grid(0, 60_000, 3);
|
||||
let schema = evaluated_schema(Arc::clone(&grid));
|
||||
// What `absent_labels` derives from `up{job="x"}`: the name is not one of them.
|
||||
let labels = MetricName::try_new(
|
||||
let labels = SeriesLabels::try_new(
|
||||
None,
|
||||
vec![Label {
|
||||
name: "job".into(),
|
||||
@@ -8357,7 +8357,7 @@ fn histogram_quantile_reads_the_buckets_of_the_whole_vector() {
|
||||
))
|
||||
.unwrap();
|
||||
let bucket = |le: &str| {
|
||||
MetricName::try_new(
|
||||
SeriesLabels::try_new(
|
||||
Some("m".into()),
|
||||
vec![
|
||||
Label {
|
||||
@@ -8405,7 +8405,7 @@ fn histogram_quantile_reads_the_pieces_of_one_label_set_as_one_series() {
|
||||
))
|
||||
.unwrap();
|
||||
let metric = |tags: &[(&str, &str)]| {
|
||||
MetricName::try_new(
|
||||
SeriesLabels::try_new(
|
||||
Some("m".into()),
|
||||
tags.iter()
|
||||
.map(|(name, value)| Label {
|
||||
|
||||
@@ -33,7 +33,7 @@ use std::sync::Arc;
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::samples::{FieldSpec, SeriesSchema};
|
||||
use datatypes::series::time::EvalGrid;
|
||||
use datatypes::series::{MetricName, SeriesOrdering};
|
||||
use datatypes::series::{SeriesLabels, SeriesOrdering};
|
||||
|
||||
use crate::histogram_eval::HistogramFunction;
|
||||
use crate::map::MathOp;
|
||||
@@ -278,7 +278,7 @@ pub enum BoundVectorOp {
|
||||
Sort(SortOrder),
|
||||
/// `absent`: `1` under `labels` at every point where the input holds no sample. The labels are
|
||||
/// what the compiler derives from the argument's matchers.
|
||||
Absent { labels: MetricName },
|
||||
Absent { labels: SeriesLabels },
|
||||
/// `histogram_quantile` or `histogram_fraction`: each classic histogram is read from the bucket
|
||||
/// series that share its labels, so this too reads the whole vector at a point.
|
||||
Histogram(HistogramFunction),
|
||||
|
||||
@@ -21,7 +21,7 @@ use common_query::prometheus::is_prometheus_stale_nan;
|
||||
use datafusion::arrow::array::{Array, Float64Array};
|
||||
use datafusion::arrow::buffer::Buffer;
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::MetricName;
|
||||
use datatypes::series::SeriesLabels;
|
||||
use datatypes::series::histogram::CounterResetHint;
|
||||
use datatypes::series::raw::RawSeriesChunk;
|
||||
use datatypes::series::samples::{
|
||||
@@ -275,7 +275,7 @@ fn flush_batch(
|
||||
struct SeriesState {
|
||||
/// `None` for evaluated input, which arrives as one complete series.
|
||||
primary_key: Option<Buffer>,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
/// Largest source timestamp retained so far, or `None` while the series holds no sample: a
|
||||
/// closing chunk of a series that never produced a value carries no position to read.
|
||||
last_ts: Option<i64>,
|
||||
|
||||
@@ -34,7 +34,7 @@ use datatypes::series::samples::{
|
||||
SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpec, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
use rand::rngs::StdRng;
|
||||
use rand::{Rng, SeedableRng};
|
||||
|
||||
@@ -108,8 +108,8 @@ fn grid(start_ms: i64, step_ms: i64, len: u64) -> Arc<EvalGrid> {
|
||||
Arc::new(EvalGrid::try_new(GridSpec::try_new(start_ms, step_ms, len).unwrap()).unwrap())
|
||||
}
|
||||
|
||||
fn metric(host: u64) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn metric(host: u64) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(Arc::from("http_requests")),
|
||||
vec![Label {
|
||||
name: Arc::from("host"),
|
||||
@@ -135,7 +135,7 @@ fn per_point_probe_evaluator(
|
||||
}
|
||||
|
||||
/// The metric of a result of `function` over the series of `metric(host)`.
|
||||
fn output_metric(function: RangeFunction, host: u64) -> MetricName {
|
||||
fn output_metric(function: RangeFunction, host: u64) -> SeriesLabels {
|
||||
let mut metric = metric(host);
|
||||
if function.drops_metric_name() {
|
||||
metric.remove("__name__");
|
||||
@@ -356,7 +356,7 @@ fn fold_chunks(chunks: &[EvaluatedChunk], schema: &Arc<SeriesSchema>) -> Option<
|
||||
fn dense_series(
|
||||
rows: &[Option<Vec<Option<GridSample>>>],
|
||||
schema: Arc<SeriesSchema>,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
) -> Option<Series> {
|
||||
let start = rows.iter().position(Option::is_some)?;
|
||||
let end = rows.iter().rposition(Option::is_some)? + 1;
|
||||
@@ -2958,7 +2958,7 @@ fn range_functions_drop_metadata_labels() {
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
let input = MetricName::try_new(
|
||||
let input = SeriesLabels::try_new(
|
||||
Some(Arc::from("m")),
|
||||
labels(&["__type__", "__unit__", "host"]),
|
||||
)
|
||||
@@ -2969,7 +2969,7 @@ fn range_functions_drop_metadata_labels() {
|
||||
anchor_ms: None,
|
||||
};
|
||||
let rows: Vec<Row> = vec![(1_000, vec![Some(1.0)]), (2_000, vec![Some(2.0)])];
|
||||
let nameless = MetricName::try_new(None, labels(&["host"])).unwrap();
|
||||
let nameless = SeriesLabels::try_new(None, labels(&["host"])).unwrap();
|
||||
for (function, expected) in [
|
||||
(RangeFunction::Rate, nameless.clone()),
|
||||
(RangeFunction::MadOverTime, nameless.clone()),
|
||||
@@ -3356,7 +3356,7 @@ fn absent_over_time_is_absent_over_present_over_time() {
|
||||
};
|
||||
let actual = absent(&schema, &present, absent_labels(&matchers).unwrap()).unwrap();
|
||||
let (expected, labels) = expected.unwrap_or_else(|| {
|
||||
let none = MetricName::try_new(None, Vec::new()).unwrap();
|
||||
let none = SeriesLabels::try_new(None, Vec::new()).unwrap();
|
||||
(vec![vec![None]; grid_spec[2] as usize], none)
|
||||
});
|
||||
// `absent` over single-field inputs writes a value at every point where it is absent, so
|
||||
@@ -3551,7 +3551,7 @@ fn evaluated_histograms_drop_counter_reset_hints() {
|
||||
fn empty_series(
|
||||
schema: &Arc<SeriesSchema>,
|
||||
grid: &Arc<EvalGrid>,
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
at: usize,
|
||||
) -> Series {
|
||||
let fields = SeriesFields::try_from_vec(vec![Samples::from_float(Float64Array::from(Vec::<
|
||||
|
||||
@@ -26,7 +26,7 @@ use std::sync::Arc;
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::samples::{RowCursor, SampleRef, Series, SeriesSchema};
|
||||
use datatypes::series::time::union_positions;
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
|
||||
use crate::go_sort;
|
||||
use crate::grid_series::{GridSeriesBuilder, external, owned};
|
||||
@@ -258,7 +258,7 @@ pub fn limit_ratio(ratio: f64, schema: &SeriesSchema, series: &[Series]) -> Resu
|
||||
|
||||
/// Prometheus `HashRatioSampler.SampleOffset`: the xxHash64 of the labels as `stringlabels`
|
||||
/// encodes them, each name and value prefixed by its length, over `u64::MAX`.
|
||||
fn sample_offset(metric: &MetricName) -> f64 {
|
||||
fn sample_offset(metric: &SeriesLabels) -> f64 {
|
||||
let mut data = Vec::new();
|
||||
for (name, value) in labels_with_name(metric) {
|
||||
// Prometheus label sets hold no empty value.
|
||||
@@ -300,7 +300,7 @@ pub fn scalar(schema: &SeriesSchema, series: &[Series]) -> Result<Series> {
|
||||
let value = if count == 1 { value } else { Some(GO_NAN) };
|
||||
builder.push(point, &[value])?;
|
||||
}
|
||||
let empty = MetricName::try_new(None, Vec::new()).map_err(external)?;
|
||||
let empty = SeriesLabels::try_new(None, Vec::new()).map_err(external)?;
|
||||
// Every grid point is written above, with a value or a NaN, so the result is one run over the
|
||||
// grid and never empty. A different shape would mean this invariant broke, and returning it
|
||||
// silently would hide it.
|
||||
@@ -328,7 +328,7 @@ pub fn scalar(schema: &SeriesSchema, series: &[Series]) -> Result<Series> {
|
||||
pub fn absent(
|
||||
schema: &SeriesSchema,
|
||||
series: &[Series],
|
||||
labels: MetricName,
|
||||
labels: SeriesLabels,
|
||||
) -> Result<Option<Series>> {
|
||||
let points = grid_points(schema, series)?;
|
||||
let fields = schema.fields.len();
|
||||
@@ -387,7 +387,7 @@ pub enum MatchOp {
|
||||
/// moving the matchers that narrow the result before those that only subtract from it; that is
|
||||
/// the order users see whenever the storage holds data, and the order used here. It changes the
|
||||
/// result only when a name has both an equality and another matcher.
|
||||
pub fn absent_labels(matchers: &[LabelMatcher]) -> Result<MetricName> {
|
||||
pub fn absent_labels(matchers: &[LabelMatcher]) -> Result<SeriesLabels> {
|
||||
let must_be_set: Vec<&str> = matchers
|
||||
.iter()
|
||||
.filter(|matcher| !matcher.matches_empty)
|
||||
@@ -421,7 +421,7 @@ pub fn absent_labels(matchers: &[LabelMatcher]) -> Result<MetricName> {
|
||||
}
|
||||
}
|
||||
labels.retain(|label| !label.value.is_empty());
|
||||
MetricName::try_new(None, labels).map_err(external)
|
||||
SeriesLabels::try_new(None, labels).map_err(external)
|
||||
}
|
||||
|
||||
/// Orders the series of an instant result. A range result keeps its order: Prometheus does not
|
||||
@@ -544,7 +544,7 @@ fn k_param(k: f64, series: usize) -> Result<Option<usize>> {
|
||||
/// Label pairs identifying a group; empty values are absent, as in Prometheus.
|
||||
type GroupKey = Vec<(Arc<str>, Arc<str>)>;
|
||||
|
||||
fn group_key(metric: &MetricName, grouping: &Grouping) -> GroupKey {
|
||||
fn group_key(metric: &SeriesLabels, grouping: &Grouping) -> GroupKey {
|
||||
let mut key: Vec<_> = labels_with_name(metric)
|
||||
.into_iter()
|
||||
.filter(|(name, value)| {
|
||||
@@ -560,7 +560,7 @@ fn group_key(metric: &MetricName, grouping: &Grouping) -> GroupKey {
|
||||
}
|
||||
|
||||
/// The label pairs of `metric` with `__name__` among them, sorted by name.
|
||||
fn labels_with_name(metric: &MetricName) -> Vec<(Arc<str>, Arc<str>)> {
|
||||
fn labels_with_name(metric: &SeriesLabels) -> Vec<(Arc<str>, Arc<str>)> {
|
||||
let mut labels: Vec<_> = metric
|
||||
.tags()
|
||||
.iter()
|
||||
@@ -574,7 +574,7 @@ fn labels_with_name(metric: &MetricName) -> Vec<(Arc<str>, Arc<str>)> {
|
||||
}
|
||||
|
||||
/// Prometheus `labels.Compare`: label pairs in name order, then the shorter set first.
|
||||
fn compare_labels(a: &MetricName, b: &MetricName) -> Ordering {
|
||||
fn compare_labels(a: &SeriesLabels, b: &SeriesLabels) -> Ordering {
|
||||
labels_with_name(a).cmp(&labels_with_name(b))
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use datatypes::series::samples::{
|
||||
FieldSpec, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpec, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
|
||||
use super::{
|
||||
Grouping, LabelMatcher, MatchOp, SortOrder, absent, absent_labels, limit_ratio, limitk,
|
||||
@@ -50,7 +50,7 @@ fn schema(points: u64, fields: usize) -> SeriesSchema {
|
||||
}
|
||||
|
||||
/// Parses `name=value,...`, with `__name__` as the metric name; `-` is no labels.
|
||||
fn metric(labels: &str) -> MetricName {
|
||||
fn metric(labels: &str) -> SeriesLabels {
|
||||
let mut name = None;
|
||||
let mut tags = Vec::new();
|
||||
for pair in labels.split(',').filter(|pair| *pair != "-") {
|
||||
@@ -64,7 +64,7 @@ fn metric(labels: &str) -> MetricName {
|
||||
});
|
||||
}
|
||||
}
|
||||
MetricName::try_new(name, tags).unwrap()
|
||||
SeriesLabels::try_new(name, tags).unwrap()
|
||||
}
|
||||
|
||||
fn dense(points: usize, values: &str) -> Dense {
|
||||
@@ -81,7 +81,7 @@ fn dense(points: usize, values: &str) -> Dense {
|
||||
///
|
||||
/// An *input*, so the holes stay nulls inside one series: the builder would cut them into pieces,
|
||||
/// and the operators under test take one series per input.
|
||||
fn build(schema: &SeriesSchema, metric: MetricName, dense: &Dense) -> Option<Series> {
|
||||
fn build(schema: &SeriesSchema, metric: SeriesLabels, dense: &Dense) -> Option<Series> {
|
||||
let start = dense
|
||||
.iter()
|
||||
.position(|row| row.iter().any(Option::is_some))?;
|
||||
@@ -472,7 +472,7 @@ fn check_cases(
|
||||
}
|
||||
|
||||
/// The fixture's label rendering: `name=value` pairs in name order, `-` when empty.
|
||||
fn render(metric: &MetricName) -> String {
|
||||
fn render(metric: &SeriesLabels) -> String {
|
||||
let mut labels: Vec<(String, String)> = metric
|
||||
.tags()
|
||||
.iter()
|
||||
|
||||
@@ -35,7 +35,7 @@ use datatypes::series::frame::LabelDecodeSpec;
|
||||
use datatypes::series::raw::{RawSeriesChunk, RawTimestamps};
|
||||
use datatypes::series::samples::{FieldSpec, SampleRef, Samples, SeriesFields, SeriesSchema};
|
||||
use datatypes::series::time::{EvalGrid, GridSpec};
|
||||
use datatypes::series::{MetricName, SeriesOrdering};
|
||||
use datatypes::series::{SeriesLabels, SeriesOrdering};
|
||||
use futures::{Stream, StreamExt, TryStreamExt};
|
||||
use mito_codec::row_converter::{DensePrimaryKeyCodec, PrimaryKeyCodec, SortField};
|
||||
use store_api::codec::PrimaryKeyEncoding;
|
||||
@@ -1663,7 +1663,7 @@ async fn ordered_input_contract_rejects_bad_key_time_and_finality_transitions()
|
||||
"explicit metric in primary-key mode",
|
||||
vec![RawSeriesChunk {
|
||||
primary_key: a.clone(),
|
||||
metric: Some(MetricName::try_new(None, vec![]).unwrap()),
|
||||
metric: Some(SeriesLabels::try_new(None, vec![]).unwrap()),
|
||||
time: RawTimestamps::try_new(ScalarBuffer::from(vec![1])).unwrap(),
|
||||
fields: SeriesFields::one(Samples::from_float(Float64Array::from(vec![1.0]))),
|
||||
is_last: true,
|
||||
|
||||
@@ -36,7 +36,7 @@ use datatypes::series::samples::{
|
||||
DenseSamplesRef, FieldSpec, HistogramSamples, SampleRef, Samples, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridSpec};
|
||||
use datatypes::series::{Label, MetricName, SeriesOrdering};
|
||||
use datatypes::series::{Label, SeriesLabels, SeriesOrdering};
|
||||
use futures::{Stream, StreamExt};
|
||||
use mito_codec::row_converter::{
|
||||
DensePrimaryKeyCodec, PrimaryKeyCodec, SortField, SparsePrimaryKeyCodec,
|
||||
@@ -161,7 +161,7 @@ fn schema_with_fields(names: &[&str]) -> Arc<SeriesSchema> {
|
||||
})
|
||||
}
|
||||
|
||||
fn chunk(read_key: Buffer, metric: Option<MetricName>, final_chunk: bool) -> RawSeriesChunk {
|
||||
fn chunk(read_key: Buffer, metric: Option<SeriesLabels>, final_chunk: bool) -> RawSeriesChunk {
|
||||
let times = ScalarBuffer::from(vec![100, 200]);
|
||||
RawSeriesChunk::try_new(
|
||||
&schema(),
|
||||
@@ -321,7 +321,7 @@ async fn materializes_complete_labels_without_changing_raw_chunks() {
|
||||
vec![Poll::Ready(Some(Ok(chunk(
|
||||
Buffer::from(vec![1, 2]),
|
||||
Some(
|
||||
MetricName::try_new(
|
||||
SeriesLabels::try_new(
|
||||
None,
|
||||
vec![Label {
|
||||
name: Arc::from("x"),
|
||||
@@ -339,7 +339,7 @@ async fn materializes_complete_labels_without_changing_raw_chunks() {
|
||||
assert_eq!(metric.name(), None);
|
||||
assert_eq!(metric.get("x"), Some(""));
|
||||
|
||||
let explicit_metric = MetricName::try_new(
|
||||
let explicit_metric = SeriesLabels::try_new(
|
||||
Some(Arc::from("explicit_metric")),
|
||||
vec![Label {
|
||||
name: Arc::from("host"),
|
||||
@@ -732,13 +732,13 @@ async fn upstream_error_and_decode_error_drop_source_terminally() {
|
||||
vec![
|
||||
Poll::Ready(Some(Ok(chunk(
|
||||
Buffer::from(vec![3]),
|
||||
Some(MetricName::try_new(None, vec![]).unwrap()),
|
||||
Some(SeriesLabels::try_new(None, vec![]).unwrap()),
|
||||
false,
|
||||
)))),
|
||||
Poll::Ready(Some(Err(upstream))),
|
||||
Poll::Ready(Some(Ok(chunk(
|
||||
Buffer::from(vec![4]),
|
||||
Some(MetricName::try_new(None, vec![]).unwrap()),
|
||||
Some(SeriesLabels::try_new(None, vec![]).unwrap()),
|
||||
true,
|
||||
)))),
|
||||
],
|
||||
@@ -857,14 +857,14 @@ async fn constructor_and_mode_errors_drop_input_without_polling_ahead() {
|
||||
|
||||
let malformed_shape = RawSeriesChunk {
|
||||
primary_key: Buffer::from(vec![1]),
|
||||
metric: Some(MetricName::try_new(None, vec![]).unwrap()),
|
||||
metric: Some(SeriesLabels::try_new(None, vec![]).unwrap()),
|
||||
time: RawTimestamps::try_new(ScalarBuffer::from(vec![100, 200])).unwrap(),
|
||||
fields: SeriesFields::one(Samples::from_float(Float64Array::from(vec![1.0]))),
|
||||
is_last: false,
|
||||
};
|
||||
let malformed_empty_time = RawSeriesChunk {
|
||||
primary_key: Buffer::from(vec![2]),
|
||||
metric: Some(MetricName::try_new(None, vec![]).unwrap()),
|
||||
metric: Some(SeriesLabels::try_new(None, vec![]).unwrap()),
|
||||
time: RawTimestamps::try_new(ScalarBuffer::from(Vec::<i64>::new())).unwrap(),
|
||||
fields: SeriesFields::one(Samples::from_float(Float64Array::from(Vec::<f64>::new()))),
|
||||
is_last: false,
|
||||
@@ -888,7 +888,7 @@ async fn constructor_and_mode_errors_drop_input_without_polling_ahead() {
|
||||
for (binding, metric) in [
|
||||
(
|
||||
source(PrimaryKeyEncoding::Dense),
|
||||
Some(MetricName::try_new(None, vec![]).unwrap()),
|
||||
Some(SeriesLabels::try_new(None, vec![]).unwrap()),
|
||||
),
|
||||
(RawLabelSource::Explicit, None),
|
||||
] {
|
||||
|
||||
@@ -30,7 +30,7 @@ use datatypes::series::samples::{
|
||||
DenseSamplesRef, FieldSpec, RowCursor, SampleRef, Series, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridRunPair, GridSpan, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
|
||||
use crate::grid_series::{GridSample, GridSeriesBuilder, METADATA_LABELS, external, owned};
|
||||
use crate::histogram_eval::float_histogram::FloatHistogram;
|
||||
@@ -306,7 +306,7 @@ const SORT_ROW_BYTES: usize =
|
||||
|
||||
/// One row of the merge's table, charged the same way.
|
||||
const MERGE_SLOT_BYTES: usize =
|
||||
2 * std::mem::size_of::<(GroupKey, (MetricName, Vec<(usize, usize, GridSample)>))>();
|
||||
2 * std::mem::size_of::<(GroupKey, (SeriesLabels, Vec<(usize, usize, GridSample)>))>();
|
||||
|
||||
/// One row of the builder's histogram table: the scalar columns and the seven list offsets.
|
||||
const HISTOGRAM_ROW_BYTES: usize = 4 * std::mem::size_of::<f64>()
|
||||
@@ -462,7 +462,7 @@ fn field_metadata_bytes(
|
||||
|
||||
/// The series of `operand` with the most labels: the widest label set one pairing of its field can
|
||||
/// build.
|
||||
fn widest_metric<'a>(operand: &'a Operand<'_>) -> Option<&'a MetricName> {
|
||||
fn widest_metric<'a>(operand: &'a Operand<'_>) -> Option<&'a SeriesLabels> {
|
||||
operand
|
||||
.series
|
||||
.iter()
|
||||
@@ -482,8 +482,8 @@ fn widest_metric<'a>(operand: &'a Operand<'_>) -> Option<&'a MetricName> {
|
||||
/// it, and a pairing whose axes share no position still pays it, because the label set is built
|
||||
/// before the axes are intersected.
|
||||
fn pair_bytes(
|
||||
many: &MetricName,
|
||||
one: &MetricName,
|
||||
many: &SeriesLabels,
|
||||
one: &SeriesLabels,
|
||||
matching: &BinaryMatching,
|
||||
include: &[Arc<str>],
|
||||
) -> usize {
|
||||
@@ -516,8 +516,8 @@ fn pair_bytes(
|
||||
}
|
||||
|
||||
/// The label text `result_metric` copies from the one side: the value of every included label it
|
||||
/// sets, and the name of a label it inserts, since `MetricName::set` copies that as well.
|
||||
fn copied_bytes(one: &MetricName, include: &[Arc<str>]) -> usize {
|
||||
/// sets, and the name of a label it inserts, since `SeriesLabels::set` copies that as well.
|
||||
fn copied_bytes(one: &SeriesLabels, include: &[Arc<str>]) -> usize {
|
||||
include
|
||||
.iter()
|
||||
.fold(0usize, |bytes, name| match one.get(name) {
|
||||
@@ -530,7 +530,7 @@ fn copied_bytes(one: &MetricName, include: &[Arc<str>]) -> usize {
|
||||
|
||||
/// The key `key_of` files a result label set under: every label with a value and the name, each
|
||||
/// charged twice for the growth of the key's `Vec`, plus the name string it copies.
|
||||
fn result_key_bytes(metric: &MetricName) -> usize {
|
||||
fn result_key_bytes(metric: &SeriesLabels) -> usize {
|
||||
metric
|
||||
.tags()
|
||||
.len()
|
||||
@@ -541,7 +541,7 @@ fn result_key_bytes(metric: &MetricName) -> usize {
|
||||
|
||||
/// The bytes one result label set keeps once a row is filed under it: the label list and the
|
||||
/// copied strings `result_metric` leaves behind, its key and its entry in the result table.
|
||||
fn result_set_bytes(metric: &MetricName, one: &MetricName, include: &[Arc<str>]) -> usize {
|
||||
fn result_set_bytes(metric: &SeriesLabels, one: &SeriesLabels, include: &[Arc<str>]) -> usize {
|
||||
metric
|
||||
.tags()
|
||||
.len()
|
||||
@@ -592,7 +592,7 @@ fn merge_bytes(
|
||||
/// `group_key` copies an `on(...)` value with `Arc::from` and shares the `Arc` of an
|
||||
/// `ignoring(...)` label, so only `on(...)` adds string bytes. The pairs are charged twice because
|
||||
/// the key is collected into a `Vec` that grows by doubling.
|
||||
fn match_key_bytes(metric: &MetricName, labels: &MatchingLabels) -> usize {
|
||||
fn match_key_bytes(metric: &SeriesLabels, labels: &MatchingLabels) -> usize {
|
||||
match labels {
|
||||
MatchingLabels::On(names) => {
|
||||
names
|
||||
@@ -615,7 +615,7 @@ fn match_key_bytes(metric: &MetricName, labels: &MatchingLabels) -> usize {
|
||||
|
||||
/// The bytes `render` writes for a label set built from `metric`: each label as `name="value"`,
|
||||
/// the braces and separators between them, and the metric's name.
|
||||
fn label_text_bytes(metric: &MetricName) -> usize {
|
||||
fn label_text_bytes(metric: &SeriesLabels) -> usize {
|
||||
let named = metric
|
||||
.name()
|
||||
.map_or(0, |name| name.len().saturating_add(10));
|
||||
@@ -1040,7 +1040,7 @@ impl Pairs<'_> {
|
||||
fn apply(
|
||||
&mut self,
|
||||
group: usize,
|
||||
metric: &MetricName,
|
||||
metric: &SeriesLabels,
|
||||
point: usize,
|
||||
many_value: SampleRef<'_>,
|
||||
one_value: SampleRef<'_>,
|
||||
@@ -1101,7 +1101,7 @@ impl Pairs<'_> {
|
||||
}
|
||||
|
||||
/// The labels Prometheus gives a fill sample: the match group of the sample it pairs with.
|
||||
fn metric_of(key: &GroupKey) -> Result<MetricName> {
|
||||
fn metric_of(key: &GroupKey) -> Result<SeriesLabels> {
|
||||
let mut name = None;
|
||||
let mut labels = Vec::with_capacity(key.len());
|
||||
for (label, value) in key {
|
||||
@@ -1114,7 +1114,7 @@ fn metric_of(key: &GroupKey) -> Result<MetricName> {
|
||||
});
|
||||
}
|
||||
}
|
||||
MetricName::try_new(name, labels).map_err(external)
|
||||
SeriesLabels::try_new(name, labels).map_err(external)
|
||||
}
|
||||
|
||||
fn earliest_error(errors: Vec<(usize, u8, String)>) -> Result<()> {
|
||||
@@ -1250,7 +1250,7 @@ fn merge_fields(
|
||||
budget.phase(merge_bytes(merge.0, sets, width, merge.1, merge.2))?;
|
||||
}
|
||||
// Per label set: the metric and its `(point, field, value)` samples.
|
||||
type Merged = (MetricName, Vec<(usize, usize, GridSample)>);
|
||||
type Merged = (SeriesLabels, Vec<(usize, usize, GridSample)>);
|
||||
let mut merged: HashMap<GroupKey, Merged> = HashMap::new();
|
||||
for (field, results) in fields.into_iter().enumerate() {
|
||||
for (key, rows) in results.series {
|
||||
@@ -1325,7 +1325,7 @@ fn same_grid(lhs: &SeriesSchema, rhs: &SeriesSchema) -> Result<Arc<EvalGrid>> {
|
||||
/// Prometheus.
|
||||
type GroupKey = Vec<(Arc<str>, Arc<str>)>;
|
||||
|
||||
fn group_key(metric: &MetricName, labels: &MatchingLabels) -> GroupKey {
|
||||
fn group_key(metric: &SeriesLabels, labels: &MatchingLabels) -> GroupKey {
|
||||
let mut key: GroupKey = match labels {
|
||||
MatchingLabels::On(names) => names
|
||||
.iter()
|
||||
@@ -1346,7 +1346,7 @@ fn group_key(metric: &MetricName, labels: &MatchingLabels) -> GroupKey {
|
||||
key
|
||||
}
|
||||
|
||||
fn key_of(metric: &MetricName) -> GroupKey {
|
||||
fn key_of(metric: &SeriesLabels) -> GroupKey {
|
||||
let mut key = group_key(metric, &MatchingLabels::Ignoring(Vec::new()));
|
||||
if let Some(name) = metric.name() {
|
||||
key.insert(0, (Arc::from("__name__"), Arc::from(name)));
|
||||
@@ -1424,12 +1424,12 @@ fn overlap(
|
||||
}
|
||||
|
||||
fn result_metric(
|
||||
many: &MetricName,
|
||||
one: &MetricName,
|
||||
many: &SeriesLabels,
|
||||
one: &SeriesLabels,
|
||||
matching: &BinaryMatching,
|
||||
include: &[Arc<str>],
|
||||
drop_name: bool,
|
||||
) -> Result<MetricName> {
|
||||
) -> Result<SeriesLabels> {
|
||||
let mut metric = many.clone();
|
||||
if drop_name {
|
||||
metric.remove_all(&METADATA_LABELS);
|
||||
@@ -1675,7 +1675,7 @@ struct Results {
|
||||
/// Rows in arrival order: their points, the match group each came from, and their values;
|
||||
/// `None` is a match the operator filtered.
|
||||
struct ResultRows {
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
points: Vec<usize>,
|
||||
groups: Vec<usize>,
|
||||
values: Vec<Option<GridSample>>,
|
||||
@@ -1707,7 +1707,7 @@ impl Results {
|
||||
/// payload is charged here, where the value is retained, and never per grid point of a float.
|
||||
fn insert(
|
||||
&mut self,
|
||||
metric: &MetricName,
|
||||
metric: &SeriesLabels,
|
||||
group: usize,
|
||||
point: usize,
|
||||
value: Option<GridSample>,
|
||||
|
||||
@@ -22,7 +22,7 @@ use datatypes::series::samples::{
|
||||
FieldSpec, HistogramSamples, RowCursor, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridRange, GridSpec, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
use rand::rngs::StdRng;
|
||||
use rand::{Rng, SeedableRng};
|
||||
|
||||
@@ -70,10 +70,10 @@ fn schema(fields: usize, grid: &Arc<EvalGrid>) -> SeriesSchema {
|
||||
}
|
||||
}
|
||||
|
||||
fn metric(labels: &Labels) -> MetricName {
|
||||
fn metric(labels: &Labels) -> SeriesLabels {
|
||||
let mut labels = labels.clone();
|
||||
let name = labels.remove("__name__").map(Arc::from);
|
||||
MetricName::try_new(
|
||||
SeriesLabels::try_new(
|
||||
name,
|
||||
labels
|
||||
.into_iter()
|
||||
@@ -86,7 +86,7 @@ fn metric(labels: &Labels) -> MetricName {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn labels_of(metric: &MetricName) -> Labels {
|
||||
fn labels_of(metric: &SeriesLabels) -> Labels {
|
||||
let mut labels: Labels = metric
|
||||
.tags()
|
||||
.iter()
|
||||
|
||||
@@ -29,7 +29,7 @@ use datatypes::series::samples::{
|
||||
FieldSpec, SampleRef, Samples, Series, SeriesFields, SeriesSchema,
|
||||
};
|
||||
use datatypes::series::time::{EvalGrid, GridSpan, GridSpec, TimeAxis};
|
||||
use datatypes::series::{Label, MetricName, SeriesOrdering};
|
||||
use datatypes::series::{Label, SeriesLabels, SeriesOrdering};
|
||||
use promql::evaluated::EvaluatedChunk;
|
||||
use promql::map::MathOp;
|
||||
use promql::native::execute::{NativeExecutionState, NativeExecutor};
|
||||
@@ -52,8 +52,8 @@ fn evaluated_schema(grid: &Arc<EvalGrid>) -> Arc<SeriesSchema> {
|
||||
}
|
||||
|
||||
/// `name{host="h1",job="x"}`, the label set all three inputs of the tree share.
|
||||
fn metric(name: &str) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn metric(name: &str) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(name.into()),
|
||||
vec![
|
||||
Label {
|
||||
|
||||
@@ -124,7 +124,7 @@ use std::time::Duration;
|
||||
use datafusion::error::{DataFusionError, Result};
|
||||
use datatypes::series::samples::SeriesSchema;
|
||||
use datatypes::series::time::{EvalGrid, GridSpec};
|
||||
use datatypes::series::{MetricName, SeriesOrdering};
|
||||
use datatypes::series::{SeriesLabels, SeriesOrdering};
|
||||
use promql::histogram_eval::HistogramFunction;
|
||||
use promql::map::{ArithmeticOp, ComparisonOp, MathOp};
|
||||
use promql::map_time::DateFunction;
|
||||
@@ -793,7 +793,7 @@ fn vector_op<'a>(
|
||||
///
|
||||
/// `__field__`, `__schema__` and `__database__` choose what is read rather than match a label, so
|
||||
/// they are not labels of the answer, as in the existing planner.
|
||||
fn absent_labels_of(expr: &PromExpr) -> Result<MetricName> {
|
||||
fn absent_labels_of(expr: &PromExpr) -> Result<SeriesLabels> {
|
||||
let PromExpr::VectorSelector(selector) = unparen(expr) else {
|
||||
return absent_labels(&[]);
|
||||
};
|
||||
|
||||
@@ -23,7 +23,7 @@ use datatypes::arrow::buffer::{Buffer, ScalarBuffer};
|
||||
use datatypes::series::SeriesOrdering;
|
||||
use datatypes::series::raw::{RawSeriesChunk, RawTimestamps};
|
||||
use datatypes::series::samples::{FieldSpec, SampleRef, Samples, SeriesFields, SeriesSchema};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
use promql::evaluated::EvaluatedChunk;
|
||||
use promql::map::MathOp;
|
||||
use promql::native::execute::{NativeExecutionState, NativeExecutor};
|
||||
@@ -2379,7 +2379,7 @@ fn the_batch_acceptance_queries_compile() {
|
||||
/// `values` is one sample per timestamp, and a `None` is a position whose sample is missing rather
|
||||
/// than a value: the two are not the same thing, and a broadcast has to keep the difference.
|
||||
fn raw_x(timestamps: &[i64], values: Vec<Option<f64>>, is_last: bool) -> RawSeriesChunk {
|
||||
let metric = MetricName::try_new(Some("x".into()), vec![]).expect("a metric name");
|
||||
let metric = SeriesLabels::try_new(Some("x".into()), vec![]).expect("a metric name");
|
||||
RawSeriesChunk::try_new(
|
||||
&raw_schema(),
|
||||
Buffer::from_slice_ref(b"series-a"),
|
||||
@@ -3746,7 +3746,7 @@ fn whole_vector_functions_bind_a_vector_operation() {
|
||||
fn agg_raw_chunk(
|
||||
schema: &SeriesSchema,
|
||||
key: &[u8],
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
timestamps: &[i64],
|
||||
values: &[f64],
|
||||
) -> RawSeriesChunk {
|
||||
@@ -3757,7 +3757,7 @@ fn agg_raw_chunk(
|
||||
fn agg_raw_chunk_with_last(
|
||||
schema: &SeriesSchema,
|
||||
key: &[u8],
|
||||
metric: MetricName,
|
||||
metric: SeriesLabels,
|
||||
timestamps: &[i64],
|
||||
values: &[f64],
|
||||
is_last: bool,
|
||||
@@ -3774,8 +3774,8 @@ fn agg_raw_chunk_with_last(
|
||||
}
|
||||
|
||||
/// `name` with the labels in `tags`, in the order given.
|
||||
fn agg_metric(name: &str, tags: &[(&str, &str)]) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn agg_metric(name: &str, tags: &[(&str, &str)]) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(name.into()),
|
||||
tags.iter()
|
||||
.map(|(name, value)| Label {
|
||||
|
||||
@@ -564,7 +564,7 @@ pub struct SeriesInfo {
|
||||
pub primary_key: datatypes::arrow::buffer::Buffer,
|
||||
/// Complete explicit metric name and labels, not a partial label projection; or `None` for
|
||||
/// primary-key label binding (undecoded, not nameless). The metric name itself may be absent.
|
||||
pub metric: Option<datatypes::series::MetricName>,
|
||||
pub metric: Option<datatypes::series::SeriesLabels>,
|
||||
}
|
||||
|
||||
/// An immutable, finite selected set of series prepared for independent range reads.
|
||||
|
||||
@@ -31,7 +31,7 @@ use datatypes::series::frame::{
|
||||
};
|
||||
use datatypes::series::raw::{RawSeriesChunk, RawTimestamps};
|
||||
use datatypes::series::samples::{FieldSpec, Samples, SeriesFields, SeriesSchema};
|
||||
use datatypes::series::{Label, MetricName};
|
||||
use datatypes::series::{Label, SeriesLabels};
|
||||
use futures::{Stream, StreamExt};
|
||||
|
||||
use crate::codec::PrimaryKeyEncoding;
|
||||
@@ -192,8 +192,8 @@ fn declared_decode_spec(source: &RawLabelSource) -> Option<LabelDecodeSpec> {
|
||||
Some(description)
|
||||
}
|
||||
|
||||
fn metric(host: &str) -> MetricName {
|
||||
MetricName::try_new(
|
||||
fn metric(host: &str) -> SeriesLabels {
|
||||
SeriesLabels::try_new(
|
||||
Some(Arc::from("cpu")),
|
||||
vec![Label {
|
||||
name: Arc::from("host"),
|
||||
@@ -242,7 +242,7 @@ fn schema() -> Arc<SeriesSchema> {
|
||||
|
||||
fn chunk(
|
||||
key: &[u8],
|
||||
metric: Option<MetricName>,
|
||||
metric: Option<SeriesLabels>,
|
||||
timestamp: i64,
|
||||
value: f64,
|
||||
last: bool,
|
||||
@@ -380,7 +380,7 @@ async fn prepared_source_label_binding_is_available_before_readers_and_matches_c
|
||||
assert_eq!(first.primary_key, Buffer::from(vec![0x10, 0x01]));
|
||||
assert_eq!(second.primary_key, Buffer::from(vec![0x10, 0x02]));
|
||||
assert_eq!(
|
||||
first.metric.as_ref().and_then(MetricName::name),
|
||||
first.metric.as_ref().and_then(SeriesLabels::name),
|
||||
if explicit { Some("cpu") } else { None }
|
||||
);
|
||||
assert_eq!(
|
||||
|
||||
@@ -401,7 +401,9 @@ fn chunk(schema: &SeriesSchema) -> RawSeriesChunk {
|
||||
RawSeriesChunk::try_new(
|
||||
schema,
|
||||
Buffer::from(b"complete-key".as_slice()),
|
||||
Some(datatypes::series::MetricName::try_new(Some(Arc::from("cpu_usage")), vec![]).unwrap()),
|
||||
Some(
|
||||
datatypes::series::SeriesLabels::try_new(Some(Arc::from("cpu_usage")), vec![]).unwrap(),
|
||||
),
|
||||
RawTimestamps::try_new(vec![10, 20].into()).unwrap(),
|
||||
SeriesFields::one(Samples::from_float(Float64Array::from(vec![
|
||||
Some(1.5),
|
||||
|
||||
Reference in New Issue
Block a user