mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-25 01:38:12 -07:00
global: metrics -> series rename
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
//! Common prefix/suffix detection for metric names.
|
||||
//! Common prefix/suffix detection for series names.
|
||||
//!
|
||||
//! This module provides utilities to find common prefixes and suffixes
|
||||
//! among metric names, which is used to detect pattern mode (suffix vs prefix).
|
||||
//! among series names, which is used to detect pattern mode (suffix vs prefix).
|
||||
|
||||
/// Find the longest common prefix among all strings.
|
||||
/// Returns the prefix WITH trailing underscore if found at word boundary.
|
||||
|
||||
@@ -179,7 +179,7 @@ fn collect_instance_analyses(
|
||||
) -> Option<String> {
|
||||
match node {
|
||||
TreeNode::Leaf(leaf) => {
|
||||
// Leaves return their metric name as the base
|
||||
// Leaves return their series name as the base
|
||||
Some(leaf.name().to_string())
|
||||
}
|
||||
TreeNode::Branch(children) => {
|
||||
@@ -213,7 +213,7 @@ fn collect_instance_analyses(
|
||||
if all_empty {
|
||||
// All-empty case: all children returned the same base.
|
||||
// Use shortest leaf to derive field_parts for fields whose key
|
||||
// matches the metric suffix (e.g., pct1 → suffix "pct1").
|
||||
// matches the series suffix (e.g., pct1 → suffix "pct1").
|
||||
let prefix = format!("{}_", analysis.base);
|
||||
let mut any_filled = false;
|
||||
for (field_name, child_node) in children {
|
||||
@@ -234,7 +234,7 @@ fn collect_instance_analyses(
|
||||
// If no fields could be filled and all children are the same type,
|
||||
// mark as outlier so the tree inlines instead of using identity
|
||||
// (handles patterns like period windows where field keys differ
|
||||
// from metric suffixes: all/_4y don't match 0sd/0sd_4y).
|
||||
// from series suffixes: all/_4y don't match 0sd/0sd_4y).
|
||||
// When children are different types (like absolute/rate), identity
|
||||
// is correct — each child handles its own suffixes internally.
|
||||
if !any_filled {
|
||||
@@ -462,7 +462,7 @@ fn analyze_instance(child_bases: &BTreeMap<String, String>) -> InstanceAnalysis
|
||||
|
||||
// No common prefix or suffix - use empty base so _m(base, relative) returns just the relative.
|
||||
// No common prefix or suffix — outlier naming (e.g., sopr/asopr/adj_).
|
||||
// Children have unrelated metric names that can't be parameterized.
|
||||
// Children have unrelated series names that can't be parameterized.
|
||||
let field_parts = child_bases
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), v.clone()))
|
||||
@@ -561,7 +561,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_analyze_instance_prefix_mode() {
|
||||
// Period-prefixed metrics like "1y_lump_sum_stack", "1m_lump_sum_stack"
|
||||
// Period-prefixed series like "1y_lump_sum_stack", "1m_lump_sum_stack"
|
||||
// share a common suffix "_lump_sum_stack" with different period prefixes
|
||||
let mut child_bases = BTreeMap::new();
|
||||
child_bases.insert("_1y".to_string(), "1y_lump_sum_stack".to_string());
|
||||
@@ -721,7 +721,7 @@ mod tests {
|
||||
];
|
||||
|
||||
let instance1 = InstanceAnalysis {
|
||||
base: "metric_a".to_string(),
|
||||
base: "series_a".to_string(),
|
||||
field_parts: [
|
||||
("max".to_string(), "max".to_string()),
|
||||
("min".to_string(), "min".to_string()),
|
||||
@@ -732,7 +732,7 @@ mod tests {
|
||||
has_outlier: false,
|
||||
};
|
||||
let instance2 = InstanceAnalysis {
|
||||
base: "metric_b".to_string(),
|
||||
base: "series_b".to_string(),
|
||||
field_parts: [
|
||||
("max".to_string(), "max".to_string()),
|
||||
("min".to_string(), "min".to_string()),
|
||||
@@ -882,7 +882,7 @@ mod tests {
|
||||
];
|
||||
// SOPR case: one instance has outlier naming (no common prefix)
|
||||
let normal = InstanceAnalysis {
|
||||
base: "metric".into(),
|
||||
base: "series".into(),
|
||||
field_parts: [("ratio".into(), "ratio".into()), ("value".into(), "value".into())].into_iter().collect(),
|
||||
is_suffix_mode: true, has_outlier: false,
|
||||
};
|
||||
@@ -1067,11 +1067,11 @@ mod tests {
|
||||
// Integration test: "loss" child returns same base as parent (because
|
||||
// its children like neg_realized_loss break the prefix). The mixed-empty
|
||||
// fix should fill it from shortest leaf "utxos_realized_loss".
|
||||
use brk_types::{MetricLeaf, MetricLeafWithSchema, TreeNode};
|
||||
use brk_types::{SeriesLeaf, SeriesLeafWithSchema, TreeNode};
|
||||
|
||||
fn leaf(name: &str) -> TreeNode {
|
||||
TreeNode::Leaf(MetricLeafWithSchema::new(
|
||||
MetricLeaf::new(name.into(), "f32".into(), std::collections::BTreeSet::new()),
|
||||
TreeNode::Leaf(SeriesLeafWithSchema::new(
|
||||
SeriesLeaf::new(name.into(), "f32".into(), std::collections::BTreeSet::new()),
|
||||
serde_json::Value::Null,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ pub fn get_node_fields(
|
||||
fields
|
||||
}
|
||||
|
||||
/// Detect index patterns (sets of indexes that appear together on metrics).
|
||||
/// Detect index patterns (sets of indexes that appear together on series).
|
||||
pub fn detect_index_patterns(tree: &TreeNode) -> Vec<IndexSetPattern> {
|
||||
let mut unique_index_sets: BTreeSet<BTreeSet<Index>> = BTreeSet::new();
|
||||
collect_index_sets_from_tree(tree, &mut unique_index_sets);
|
||||
@@ -85,7 +85,7 @@ pub fn detect_index_patterns(tree: &TreeNode) -> Vec<IndexSetPattern> {
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, indexes)| IndexSetPattern {
|
||||
name: format!("MetricPattern{}", i + 1),
|
||||
name: format!("SeriesPattern{}", i + 1),
|
||||
indexes,
|
||||
})
|
||||
.collect()
|
||||
@@ -147,7 +147,7 @@ impl PatternBaseResult {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the metric base for a pattern instance by analyzing direct children.
|
||||
/// Get the series base for a pattern instance by analyzing direct children.
|
||||
///
|
||||
/// Uses the shortest leaf names from direct children to find common prefix/suffix.
|
||||
///
|
||||
@@ -194,7 +194,7 @@ pub fn get_pattern_instance_base(node: &TreeNode) -> PatternBaseResult {
|
||||
}
|
||||
|
||||
// Fallback: no common prefix/suffix found - this is a root-level pattern
|
||||
// Return empty base so metric names are used directly
|
||||
// Return empty base so series names are used directly
|
||||
PatternBaseResult::empty()
|
||||
}
|
||||
|
||||
@@ -346,15 +346,15 @@ pub fn get_fields_with_child_info(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use brk_types::{MetricLeaf, MetricLeafWithSchema, TreeNode};
|
||||
use brk_types::{SeriesLeaf, SeriesLeafWithSchema, TreeNode};
|
||||
|
||||
fn make_leaf(name: &str) -> TreeNode {
|
||||
let leaf = MetricLeaf {
|
||||
let leaf = SeriesLeaf {
|
||||
name: name.to_string(),
|
||||
kind: "TestType".to_string(),
|
||||
indexes: BTreeSet::new(),
|
||||
};
|
||||
TreeNode::Leaf(MetricLeafWithSchema::new(leaf, serde_json::json!({})))
|
||||
TreeNode::Leaf(SeriesLeafWithSchema::new(leaf, serde_json::json!({})))
|
||||
}
|
||||
|
||||
fn make_branch(children: Vec<(&str, TreeNode)>) -> TreeNode {
|
||||
@@ -390,7 +390,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_get_pattern_instance_base_without_base_field() {
|
||||
// Simulates weight tree: NO base field, only suffixed metrics
|
||||
// Simulates weight tree: NO base field, only suffixed series
|
||||
let tree = make_branch(vec![
|
||||
(
|
||||
"average",
|
||||
@@ -447,7 +447,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_get_pattern_instance_base_with_mismatched_base_name() {
|
||||
// Simulates the actual bug: indexed tree's "base" field has name "weight"
|
||||
// but computed tree's derived metrics use "block_weight_*" prefix.
|
||||
// but computed tree's derived series use "block_weight_*" prefix.
|
||||
// After tree merge, we get a base field with mismatched naming.
|
||||
let tree = make_branch(vec![
|
||||
("base", make_leaf("weight")), // Outlier - doesn't match pattern
|
||||
@@ -466,11 +466,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_get_pattern_instance_base_root_level_no_common_pattern() {
|
||||
// Simulates root-level pattern with metrics that have no common prefix/suffix.
|
||||
// Simulates root-level pattern with series that have no common prefix/suffix.
|
||||
// These names have no shared prefix or suffix, even when excluding any one.
|
||||
// In this case, we should return empty base so metric names are used directly.
|
||||
// In this case, we should return empty base so series names are used directly.
|
||||
let tree = make_branch(vec![
|
||||
("alpha", make_leaf("foo_metric")),
|
||||
("alpha", make_leaf("foo_series")),
|
||||
("beta", make_leaf("bar_value")),
|
||||
("gamma", make_leaf("baz_count")),
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user