refactor(datatypes): name the PromQL series label set by what it is (#9914)

I hereby agree to the terms of the [GreptimeDB
CLA](https://github.com/GreptimeTeam/.github/blob/main/CLA.md).

## Refer to a related PR or issue link (optional)

Split out of #9868, where it did not belong: the rename is not part of
the wiring.

## What's changed and what's your intention?

`datatypes::series::MetricName` did not hold a metric name. It held the
whole
PromQL-visible label set of one series — the `__name__` value plus its
ordinary
labels — with methods for label lookup, rewriting, keeping and removing
that
operate on the whole set. The name made every call site read as if a
series were
identified by its metric name, which it is not: two series share a
metric name
and differ in their other labels.

Rename the type to `SeriesLabels` so the name says what it holds, and
state in
its doc comment what it is *not*:

- not a canonical matching/grouping identity — matching drops `__name__`
and
  compares the remaining labels canonically;
- not a storage identity — that is the read key / primary key.

The rename is mechanical: 58 files, +290/−279. No field, method, or
behaviour
changes. Identifiers that merely *begin* with the old name are untouched
—
`MetricNameLabel`, `MetricNameDiscovery`,
`PrometheusMetricNamesQueryPlan` keep
their names, since they refer to a metric name in the narrow sense and
are
correct as they are.

### Limitations

None. This is a rename; the type's representation and semantics are
unchanged.

## PR Checklist
Please convert it to a draft if some of the following conditions are not
met.

- [x] I have written the necessary rustdoc comments.
- [x] I have added the necessary unit tests and integration tests.
- [ ] This PR requires documentation updates.
- [x] API changes are backward compatible.
- [x] Schema or data changes are backward compatible.
- [ ] This PR needs to be backported to release branches, and I have
added the `backport-<target>` labels (e.g. `backport-v1.3` targets
`release/v1.3`).
This commit is contained in:
discord9
2026-10-25 04:30:30 +08:00
committed by GitHub
57 changed files with 290 additions and 280 deletions
+2 -2
View File
@@ -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),
+6 -6
View File
@@ -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"),
+8 -3
View File
@@ -55,14 +55,19 @@ 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 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));
+4 -4
View File
@@ -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,
)?)
+4 -4
View File
@@ -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,
+3 -3
View File
@@ -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,
+3 -3
View File
@@ -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"),
+3 -3
View File
@@ -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> {
+9 -9
View File
@@ -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
)
+8 -8
View File
@@ -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")],
)
+2 -2
View File
@@ -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(),
)
+4 -4
View File
@@ -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(),
}
+1 -1
View File
@@ -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 =
+9 -9
View File
@@ -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]>>,
+2 -2
View File
@@ -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>>)>,
}
+15 -12
View File
@@ -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]],
);
+3 -3
View File
@@ -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.
@@ -66,7 +66,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;
@@ -597,7 +597,7 @@ fn values_of(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,
@@ -640,8 +640,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()
@@ -1457,7 +1457,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(
@@ -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.
+6 -6
View File
@@ -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()
+5 -5
View File
@@ -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())
+9 -9
View File
@@ -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()
+3 -3
View File
@@ -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"),
+4 -4
View File
@@ -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};
@@ -102,7 +102,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
@@ -232,13 +232,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(),
+2 -2
View File
@@ -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())
+5 -5
View File
@@ -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>> {
+4 -4
View File
@@ -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],
+7 -7
View File
@@ -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 {
+2 -2
View File
@@ -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)?;
+3 -3
View File
@@ -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(),
),
+2 -2
View File
@@ -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)],
+1 -1
View File
@@ -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(),
+4 -4
View File
@@ -19,7 +19,7 @@ use std::fmt;
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 @@ impl LabelRewrite {
/// listed any number of times, and every `$` reference of a `label_replace` template can expand
/// to the whole source value. The bound counts each source once per listing and each `$` as
/// one whole source value.
pub fn written_bytes(&self, metric: &MetricName) -> usize {
pub fn written_bytes(&self, metric: &SeriesLabels) -> usize {
let value = |name: &str| metric.get(name).map_or(0, str::len);
match &self.0 {
Change::Replace {
@@ -173,7 +173,7 @@ impl LabelRewrite {
}
/// Changes `metric` the way the function changes one series.
pub fn apply(&self, metric: &mut MetricName) -> Result<()> {
pub fn apply(&self, metric: &mut SeriesLabels) -> Result<()> {
let mut value = String::new();
match &self.0 {
Change::Replace {
@@ -278,7 +278,7 @@ fn expand(regex: &Regex, captures: &regex::Captures<'_>, template: &str, out: &m
}
/// 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(());
+2 -2
View File
@@ -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)?,
)
+2 -2
View File
@@ -22,7 +22,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:?}"))
+2 -2
View File
@@ -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,
@@ -436,7 +436,7 @@ fn a_vector_operation_names_its_binding() {
),
(
BoundVectorOp::Absent {
labels: MetricName::try_new(
labels: SeriesLabels::try_new(
None,
vec![Label {
name: "job".into(),
+7 -7
View File
@@ -33,7 +33,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::{
@@ -297,7 +297,7 @@ impl InputId {
/// 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>,
}
@@ -555,7 +555,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
@@ -1029,7 +1029,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.
@@ -1816,7 +1816,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 {
@@ -1979,7 +1979,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"
@@ -4031,7 +4031,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())
})?;
+29 -29
View File
@@ -30,7 +30,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, InputId, InputSlot, NativeChunk, NativeExecutionState, NativeExecutor,
@@ -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.
@@ -276,7 +276,7 @@ fn raw_chunk(
fn raw_chunk_of(
schema: &SeriesSchema,
key: &[u8],
metric: MetricName,
metric: SeriesLabels,
timestamps: &[i64],
values: &[f64],
is_last: bool,
@@ -555,7 +555,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,
@@ -569,7 +569,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,
@@ -592,7 +592,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>,
@@ -628,8 +628,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(),
@@ -643,7 +643,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(),
@@ -654,7 +654,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> {
@@ -2599,7 +2599,7 @@ fn two_series_onto_one_label_set_after_a_window_are_rejected() {
raw_chunk_of(
&schema,
b"series-b",
MetricName::try_new(
SeriesLabels::try_new(
Some("requests".into()),
vec![Label {
name: "host".into(),
@@ -3398,7 +3398,7 @@ fn two_series_with_no_result_do_not_collide() {
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,
@@ -3427,7 +3427,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,
@@ -4703,7 +4703,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,
@@ -4719,7 +4719,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>>>,
@@ -4748,7 +4748,7 @@ fn evaluated_on(
/// `len` positions from `start`.
fn evaluated_histograms(
schema: &SeriesSchema,
metric: MetricName,
metric: SeriesLabels,
start: usize,
buckets: i32,
len: usize,
@@ -4788,8 +4788,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 {
@@ -4806,8 +4806,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 {
@@ -7013,8 +7013,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 {
@@ -7445,7 +7445,7 @@ fn a_histogram_function_maps_the_histogram_positions() {
fn a_histogram_function_names_an_emptied_closing_chunk_like_its_kernel() {
let grid = grid(0, 60_000, 2);
let schema = evaluated_schema(Arc::clone(&grid));
let metric = MetricName::try_new(
let metric = SeriesLabels::try_new(
Some("a".into()),
vec![Label {
name: "__type__".into(),
@@ -8077,7 +8077,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));
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(
InputId::new(0),
@@ -8094,7 +8094,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(
InputId::new(0),
@@ -8738,7 +8738,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(),
@@ -8920,7 +8920,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 {
@@ -8965,7 +8965,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 {
+2 -2
View File
@@ -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, NativeHistogramFunction};
use crate::map::MathOp;
@@ -289,7 +289,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),
+2 -2
View File
@@ -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::{
@@ -318,7 +318,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>,
+9 -9
View File
@@ -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;
@@ -2992,7 +2992,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"]),
)
@@ -3004,7 +3004,7 @@ fn range_functions_drop_metadata_labels() {
modifier: 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()),
@@ -3401,7 +3401,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
@@ -3598,7 +3598,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::<
+9 -9
View File
@@ -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))
}
+5 -5
View File
@@ -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()
+2 -2
View File
@@ -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,
+9 -9
View File
@@ -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),
] {
+22 -22
View File
@@ -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;
@@ -304,7 +304,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>()
@@ -460,7 +460,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()
@@ -480,8 +480,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 {
@@ -514,8 +514,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) {
@@ -528,7 +528,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()
@@ -539,7 +539,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()
@@ -590,7 +590,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
@@ -613,7 +613,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));
@@ -1047,7 +1047,7 @@ impl Pairs<'_> {
fn apply(
&mut self,
group: usize,
metric: &MetricName,
metric: &SeriesLabels,
point: usize,
many_value: SampleRef<'_>,
one_value: SampleRef<'_>,
@@ -1108,7 +1108,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 {
@@ -1121,7 +1121,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<()> {
@@ -1257,7 +1257,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 {
@@ -1332,7 +1332,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()
@@ -1353,7 +1353,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)));
@@ -1431,12 +1431,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);
@@ -1682,7 +1682,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>>,
@@ -1714,7 +1714,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>,
+4 -4
View File
@@ -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()
+3 -3
View File
@@ -28,7 +28,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::{InputId, 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 {
+2 -2
View File
@@ -134,7 +134,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, NativeHistogramFunction};
use promql::map::{ArithmeticOp, ComparisonOp, MathOp};
use promql::map_label::LabelRewrite;
@@ -866,7 +866,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(&[]);
};
+6 -6
View File
@@ -22,7 +22,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::{InputId, NativeExecutionState, NativeExecutor};
@@ -2389,7 +2389,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"),
@@ -3756,7 +3756,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 {
@@ -3767,7 +3767,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,
@@ -3784,8 +3784,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 {
+1 -1
View File
@@ -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!(
+3 -1
View File
@@ -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),