clients: snapshot

This commit is contained in:
nym21
2026-01-14 09:37:43 +01:00
parent 25a0ebe51e
commit 922a0abb60
11 changed files with 24404 additions and 3752 deletions
+41 -1
View File
@@ -123,6 +123,9 @@ pub struct PatternBaseResult {
/// Whether this instance uses suffix mode (common prefix) or prefix mode (common suffix).
/// Used to check compatibility with the pattern's mode.
pub is_suffix_mode: bool,
/// The field parts (suffix in suffix mode, prefix in prefix mode) for each field.
/// Used to check if instance field parts match the pattern's field parts.
pub field_parts: HashMap<String, String>,
}
/// Get the metric base for a pattern instance by analyzing direct children.
@@ -141,6 +144,7 @@ pub fn get_pattern_instance_base(node: &TreeNode) -> PatternBaseResult {
base: String::new(),
has_outlier: false,
is_suffix_mode: true, // default
field_parts: HashMap::new(),
};
}
@@ -150,6 +154,7 @@ pub fn get_pattern_instance_base(node: &TreeNode) -> PatternBaseResult {
base: result.base,
has_outlier: result.has_outlier,
is_suffix_mode: result.is_suffix_mode,
field_parts: result.field_parts,
};
}
@@ -168,6 +173,7 @@ pub fn get_pattern_instance_base(node: &TreeNode) -> PatternBaseResult {
base: result.base,
has_outlier: true,
is_suffix_mode: result.is_suffix_mode,
field_parts: result.field_parts,
};
}
}
@@ -179,14 +185,16 @@ pub fn get_pattern_instance_base(node: &TreeNode) -> PatternBaseResult {
base: String::new(),
has_outlier: false,
is_suffix_mode: true, // default
field_parts: HashMap::new(),
}
}
/// Result of try_find_base: base name, has_outlier flag, and is_suffix_mode flag.
/// Result of try_find_base: base name, has_outlier flag, is_suffix_mode flag, and field_parts.
struct FindBaseResult {
base: String,
has_outlier: bool,
is_suffix_mode: bool,
field_parts: HashMap<String, String>,
}
/// Try to find a common base from child names using prefix/suffix detection.
@@ -197,20 +205,52 @@ fn try_find_base(child_names: &[(String, String)], is_outlier_attempt: bool) ->
// Try common prefix first (suffix mode)
if let Some(prefix) = find_common_prefix(&leaf_names) {
let base = prefix.trim_end_matches('_').to_string();
let mut field_parts = HashMap::new();
for (field_name, leaf_name) in child_names {
// Compute the suffix part for this field
let suffix = if leaf_name == &base {
String::new()
} else {
leaf_name
.strip_prefix(&prefix)
.unwrap_or(leaf_name)
.to_string()
};
field_parts.insert(field_name.clone(), suffix);
}
return Some(FindBaseResult {
base,
has_outlier: is_outlier_attempt,
is_suffix_mode: true,
field_parts,
});
}
// Try common suffix (prefix mode)
if let Some(suffix) = find_common_suffix(&leaf_names) {
let base = suffix.trim_start_matches('_').to_string();
let mut field_parts = HashMap::new();
for (field_name, leaf_name) in child_names {
// Compute the prefix part for this field
let prefix_part = leaf_name
.strip_suffix(&suffix)
.map(|s| {
if s.is_empty() {
String::new()
} else if s.ends_with('_') {
s.to_string()
} else {
format!("{}_", s)
}
})
.unwrap_or_default();
field_parts.insert(field_name.clone(), prefix_part);
}
return Some(FindBaseResult {
base,
has_outlier: is_outlier_attempt,
is_suffix_mode: false,
field_parts,
});
}
+19 -9
View File
@@ -55,17 +55,20 @@ pub fn prepare_tree_node<'a>(
.map(|(f, _)| f.clone())
.collect();
// Skip if this matches a parameterizable pattern AND has no outlier AND mode matches
// Skip if this matches a parameterizable pattern AND has no outlier AND field parts match
let base_result = get_pattern_instance_base(node);
let mode_matches = pattern_lookup
let pattern_fully_matches = pattern_lookup
.get(&fields)
.and_then(|name| metadata.find_pattern(name))
.is_none_or(|p| p.is_suffix_mode() == base_result.is_suffix_mode);
.is_some_and(|p| {
p.is_suffix_mode() == base_result.is_suffix_mode
&& p.field_parts_match(&base_result.field_parts)
});
if let Some(pattern_name) = pattern_lookup.get(&fields)
&& pattern_name != name
&& metadata.is_parameterizable(pattern_name)
&& !base_result.has_outlier
&& mode_matches
&& pattern_fully_matches
{
return None;
}
@@ -89,16 +92,23 @@ pub fn prepare_tree_node<'a>(
.as_ref()
.is_some_and(|cf| metadata.matches_pattern(cf));
// Check if the pattern mode matches the instance mode
let mode_matches = child_fields
// Check if the pattern mode AND field parts match the instance
let pattern_fully_matches = child_fields
.as_ref()
.and_then(|cf| metadata.find_pattern_by_fields(cf))
.is_none_or(|p| p.is_suffix_mode() == base_result.is_suffix_mode);
.is_some_and(|p| {
// Mode must match (suffix vs prefix)
if p.is_suffix_mode() != base_result.is_suffix_mode {
return false;
}
// Field parts must also match
p.field_parts_match(&base_result.field_parts)
});
// should_inline determines if we generate an inline struct type
// We inline if: it's a branch AND (doesn't match any pattern OR mode doesn't match OR has outlier)
// We inline if: it's a branch AND (doesn't match any pattern OR pattern doesn't fully match OR has outlier)
let should_inline =
!is_leaf && (!matches_any_pattern || !mode_matches || base_result.has_outlier);
!is_leaf && (!matches_any_pattern || !pattern_fully_matches || base_result.has_outlier);
// Inline type name (only used when should_inline is true)
let inline_type_name = if should_inline {
+25 -1
View File
@@ -1,6 +1,6 @@
//! Structural pattern and field types.
use std::collections::BTreeSet;
use std::collections::{BTreeSet, HashMap};
use brk_types::Index;
@@ -47,6 +47,30 @@ impl StructuralPattern {
pub fn is_suffix_mode(&self) -> bool {
matches!(&self.mode, Some(PatternMode::Suffix { .. }))
}
/// Check if the given instance field parts match this pattern's field parts.
/// Returns true if all field parts in the pattern match the instance's field parts.
pub fn field_parts_match(&self, instance_field_parts: &HashMap<String, String>) -> bool {
match &self.mode {
Some(PatternMode::Suffix { relatives }) => {
// For each field in the pattern, check if the instance has the same suffix
relatives.iter().all(|(field_name, pattern_suffix)| {
instance_field_parts
.get(field_name)
.is_some_and(|instance_suffix| instance_suffix == pattern_suffix)
})
}
Some(PatternMode::Prefix { prefixes }) => {
// For each field in the pattern, check if the instance has the same prefix
prefixes.iter().all(|(field_name, pattern_prefix)| {
instance_field_parts
.get(field_name)
.is_some_and(|instance_prefix| instance_prefix == pattern_prefix)
})
}
None => false, // Non-parameterizable patterns don't use field parts
}
}
}
/// A field in a structural pattern.