use std::collections::BTreeMap;
use std::fmt::Write as _;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SubMsFeatureCategory {
HotPath,
Structural,
Auxiliary,
Reported,
Indeterminate,
}
impl SubMsFeatureCategory {
pub fn as_str(self) -> &'static str {
match self {
SubMsFeatureCategory::HotPath => "hot-path",
SubMsFeatureCategory::Structural => "structural",
SubMsFeatureCategory::Auxiliary => "auxiliary",
SubMsFeatureCategory::Reported => "reported",
SubMsFeatureCategory::Indeterminate => "indeterminate",
}
}
pub fn from_wire(s: &str) -> Option<SubMsFeatureCategory> {
match s {
"hot-path" => Some(SubMsFeatureCategory::HotPath),
"structural" => Some(SubMsFeatureCategory::Structural),
"auxiliary" => Some(SubMsFeatureCategory::Auxiliary),
"reported" => Some(SubMsFeatureCategory::Reported),
"indeterminate" => Some(SubMsFeatureCategory::Indeterminate),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SubMsStageClass {
pub p99_ns: u64,
pub category: SubMsFeatureCategory,
pub reason: String,
}
impl SubMsFeatureCategory {
fn restriction(self) -> u8 {
match self {
SubMsFeatureCategory::Auxiliary => 0,
SubMsFeatureCategory::HotPath => 1,
SubMsFeatureCategory::Structural => 2,
SubMsFeatureCategory::Reported => 3,
SubMsFeatureCategory::Indeterminate => 4,
}
}
}
pub fn roll_up_stages(stages: &BTreeMap<String, SubMsStageClass>) -> SubMsFeatureCategory {
stages
.values()
.map(|s| s.category)
.max_by_key(|c| c.restriction())
.unwrap_or(SubMsFeatureCategory::Auxiliary)
}
const STRUCTURAL_FRACTION: f64 = 0.5;
const HOT_PATH_DELTA: f64 = 0.10;
const CLAIM_LINE_NS: u64 = 1_000_000;
const INDETERMINATE_BAND: f64 = 0.25;
const BASE_DELTA_BAND: f64 = 0.05;
pub fn classify_feature(
sweep: &[(usize, u64)],
base_p99_ns: Option<u64>,
override_category: Option<SubMsFeatureCategory>,
) -> (SubMsFeatureCategory, String) {
if let Some(cat) = override_category {
return (cat, format!("override: pinned {}", cat.as_str()));
}
if sweep.is_empty() {
return (
SubMsFeatureCategory::Auxiliary,
"no hot-path workload registered".to_string(),
);
}
let (min_n, p99_at_min) = sweep.iter().min_by_key(|(n, _)| *n).copied().unwrap();
let (max_n, p99_at_max) = sweep.iter().max_by_key(|(n, _)| *n).copied().unwrap();
if max_n > min_n && p99_at_min > 0 {
let size_ratio = max_n as f64 / min_n as f64;
let p99_ratio = p99_at_max as f64 / p99_at_min as f64;
let needed = STRUCTURAL_FRACTION * (size_ratio - 1.0);
let growth = p99_ratio - 1.0;
if needed > 0.0 {
let margin = growth / needed;
if (1.0 - INDETERMINATE_BAND..=1.0 + INDETERMINATE_BAND).contains(&margin) {
return (
SubMsFeatureCategory::Indeterminate,
format!(
"p99 grew {:.1}x over {:.0}x N, against {:.1}x needed for structural - too close to call",
p99_ratio,
size_ratio,
needed + 1.0
),
);
}
}
if growth >= needed {
return (
SubMsFeatureCategory::Structural,
format!(
"p99 scales with size ({:.1}x over {:.0}x N) - O(n)+, excluded from per-op claim",
p99_ratio, size_ratio
),
);
}
}
let feature_p99 = p99_at_max.max(p99_at_min);
if feature_p99 > CLAIM_LINE_NS {
return (
SubMsFeatureCategory::Reported,
format!(
"flat per-op p99 {}ns, above the {}ms claim line - reported, not claimed",
feature_p99,
CLAIM_LINE_NS / 1_000_000
),
);
}
match base_p99_ns {
Some(base) if base > 0 => {
let excess = feature_p99 as f64 / base as f64 - 1.0;
if (HOT_PATH_DELTA - BASE_DELTA_BAND..=HOT_PATH_DELTA + BASE_DELTA_BAND)
.contains(&excess)
{
return (
SubMsFeatureCategory::Indeterminate,
format!(
"flat p99 {}ns is {:.0}% over base {}ns, against a {:.0}% hot-path guard - too close to call",
feature_p99,
excess * 100.0,
base,
HOT_PATH_DELTA * 100.0
),
);
}
if feature_p99 as f64 > base as f64 * (1.0 + HOT_PATH_DELTA) {
(
SubMsFeatureCategory::HotPath,
format!("flat per-op p99 {}ns, above base {}ns", feature_p99, base),
)
} else if feature_p99 < base {
(
SubMsFeatureCategory::Auxiliary,
format!(
"flat p99 {}ns, at or below base {}ns - no hot-path cost",
feature_p99, base
),
)
} else {
(
SubMsFeatureCategory::Auxiliary,
format!(
"flat p99 {}ns within {:.0}% of base {}ns - measured non-effect",
feature_p99,
HOT_PATH_DELTA * 100.0,
base
),
)
}
}
_ => (
SubMsFeatureCategory::HotPath,
format!("flat per-op p99 {}ns", feature_p99),
),
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Json {
Null,
Bool(bool),
Num(String),
Str(String),
Arr(Vec<Json>),
Obj(Vec<(String, Json)>),
}
impl Json {
pub fn as_object_mut(&mut self) -> Option<&mut Vec<(String, Json)>> {
match self {
Json::Obj(v) => Some(v),
_ => None,
}
}
fn get_mut<'a>(obj: &'a mut [(String, Json)], key: &str) -> Option<&'a mut Json> {
obj.iter_mut().find(|(k, _)| k == key).map(|(_, v)| v)
}
fn get(&self, key: &str) -> Option<&Json> {
match self {
Json::Obj(v) => v.iter().find(|(k, _)| k == key).map(|(_, val)| val),
_ => None,
}
}
fn remove(obj: &mut Vec<(String, Json)>, key: &str) {
obj.retain(|(k, _)| k != key);
}
fn set(obj: &mut Vec<(String, Json)>, key: &str, val: Json) {
if let Some(slot) = obj.iter_mut().find(|(k, _)| k == key) {
slot.1 = val;
} else {
obj.push((key.to_string(), val));
}
}
pub fn to_pretty(&self) -> String {
let mut s = String::new();
self.write_pretty(&mut s, 0);
s.push('\n');
s
}
fn write_pretty(&self, out: &mut String, indent: usize) {
match self {
Json::Null => out.push_str("null"),
Json::Bool(b) => out.push_str(if *b { "true" } else { "false" }),
Json::Num(n) => out.push_str(n),
Json::Str(s) => write_json_string(out, s),
Json::Arr(items) => {
if items.is_empty() {
out.push_str("[]");
return;
}
out.push_str("[\n");
for (i, it) in items.iter().enumerate() {
pad(out, indent + 1);
it.write_pretty(out, indent + 1);
if i + 1 < items.len() {
out.push(',');
}
out.push('\n');
}
pad(out, indent);
out.push(']');
}
Json::Obj(pairs) => {
if pairs.is_empty() {
out.push_str("{}");
return;
}
out.push_str("{\n");
for (i, (k, v)) in pairs.iter().enumerate() {
pad(out, indent + 1);
write_json_string(out, k);
out.push_str(": ");
v.write_pretty(out, indent + 1);
if i + 1 < pairs.len() {
out.push(',');
}
out.push('\n');
}
pad(out, indent);
out.push('}');
}
}
}
}
fn pad(out: &mut String, indent: usize) {
for _ in 0..indent {
out.push_str(" ");
}
}
fn write_json_string(out: &mut String, s: &str) {
out.push('"');
for c in s.chars() {
match c {
'"' => out.push_str("\\\""),
'\\' => out.push_str("\\\\"),
'\n' => out.push_str("\\n"),
'\r' => out.push_str("\\r"),
'\t' => out.push_str("\\t"),
c if (c as u32) < 0x20 => {
let _ = write!(out, "\\u{:04x}", c as u32);
}
c => out.push(c),
}
}
out.push('"');
}
pub fn parse_json(input: &str) -> Result<Json, String> {
let mut p = JsonParser {
bytes: input.as_bytes(),
pos: 0,
};
p.skip_ws();
let v = p.value()?;
p.skip_ws();
if p.pos != p.bytes.len() {
return Err(format!("trailing input at byte {}", p.pos));
}
Ok(v)
}
struct JsonParser<'a> {
bytes: &'a [u8],
pos: usize,
}
impl<'a> JsonParser<'a> {
fn peek(&self) -> Option<u8> {
self.bytes.get(self.pos).copied()
}
fn skip_ws(&mut self) {
while let Some(c) = self.peek() {
if c == b' ' || c == b'\t' || c == b'\n' || c == b'\r' {
self.pos += 1;
} else {
break;
}
}
}
fn value(&mut self) -> Result<Json, String> {
self.skip_ws();
match self.peek() {
Some(b'{') => self.object(),
Some(b'[') => self.array(),
Some(b'"') => Ok(Json::Str(self.string()?)),
Some(b't') | Some(b'f') => self.boolean(),
Some(b'n') => self.null(),
Some(c) if c == b'-' || c.is_ascii_digit() => self.number(),
Some(c) => Err(format!("unexpected byte {:?} at {}", c as char, self.pos)),
None => Err("unexpected end of input".to_string()),
}
}
fn object(&mut self) -> Result<Json, String> {
self.pos += 1; let mut out = Vec::new();
self.skip_ws();
if self.peek() == Some(b'}') {
self.pos += 1;
return Ok(Json::Obj(out));
}
loop {
self.skip_ws();
let key = self.string()?;
self.skip_ws();
if self.peek() != Some(b':') {
return Err(format!("expected ':' at {}", self.pos));
}
self.pos += 1;
let val = self.value()?;
out.push((key, val));
self.skip_ws();
match self.peek() {
Some(b',') => {
self.pos += 1;
}
Some(b'}') => {
self.pos += 1;
break;
}
_ => return Err(format!("expected ',' or '}}' at {}", self.pos)),
}
}
Ok(Json::Obj(out))
}
fn array(&mut self) -> Result<Json, String> {
self.pos += 1; let mut out = Vec::new();
self.skip_ws();
if self.peek() == Some(b']') {
self.pos += 1;
return Ok(Json::Arr(out));
}
loop {
let v = self.value()?;
out.push(v);
self.skip_ws();
match self.peek() {
Some(b',') => {
self.pos += 1;
}
Some(b']') => {
self.pos += 1;
break;
}
_ => return Err(format!("expected ',' or ']' at {}", self.pos)),
}
}
Ok(Json::Arr(out))
}
fn string(&mut self) -> Result<String, String> {
if self.peek() != Some(b'"') {
return Err(format!("expected string at {}", self.pos));
}
self.pos += 1;
let mut s = String::new();
loop {
match self.peek() {
None => return Err("unterminated string".to_string()),
Some(b'"') => {
self.pos += 1;
break;
}
Some(b'\\') => {
self.pos += 1;
match self.peek() {
Some(b'"') => s.push('"'),
Some(b'\\') => s.push('\\'),
Some(b'/') => s.push('/'),
Some(b'n') => s.push('\n'),
Some(b't') => s.push('\t'),
Some(b'r') => s.push('\r'),
Some(b'b') => s.push('\u{0008}'),
Some(b'f') => s.push('\u{000C}'),
Some(b'u') => {
let hex = self
.bytes
.get(self.pos + 1..self.pos + 5)
.ok_or("bad \\u escape")?;
let code = u32::from_str_radix(
std::str::from_utf8(hex).map_err(|_| "bad \\u hex")?,
16,
)
.map_err(|_| "bad \\u hex")?;
s.push(char::from_u32(code).unwrap_or('\u{FFFD}'));
self.pos += 4;
}
_ => return Err("bad escape".to_string()),
}
self.pos += 1;
}
Some(_) => {
let start = self.pos;
let ch_len = utf8_len(self.bytes[self.pos]);
self.pos += ch_len;
let slice = &self.bytes[start..self.pos.min(self.bytes.len())];
s.push_str(std::str::from_utf8(slice).map_err(|_| "bad utf8")?);
}
}
}
Ok(s)
}
fn number(&mut self) -> Result<Json, String> {
let start = self.pos;
if self.peek() == Some(b'-') {
self.pos += 1;
}
while let Some(c) = self.peek() {
if c.is_ascii_digit() || c == b'.' || c == b'e' || c == b'E' || c == b'+' || c == b'-' {
self.pos += 1;
} else {
break;
}
}
let raw = std::str::from_utf8(&self.bytes[start..self.pos]).map_err(|_| "bad number")?;
Ok(Json::Num(raw.to_string()))
}
fn boolean(&mut self) -> Result<Json, String> {
if self.bytes[self.pos..].starts_with(b"true") {
self.pos += 4;
Ok(Json::Bool(true))
} else if self.bytes[self.pos..].starts_with(b"false") {
self.pos += 5;
Ok(Json::Bool(false))
} else {
Err(format!("bad literal at {}", self.pos))
}
}
fn null(&mut self) -> Result<Json, String> {
if self.bytes[self.pos..].starts_with(b"null") {
self.pos += 4;
Ok(Json::Null)
} else {
Err(format!("bad literal at {}", self.pos))
}
}
}
fn utf8_len(b: u8) -> usize {
if b < 0x80 {
1
} else if b >> 5 == 0b110 {
2
} else if b >> 4 == 0b1110 {
3
} else {
4
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum SubMsP99Source {
Local,
Fleet,
}
impl SubMsP99Source {
pub fn as_str(self) -> &'static str {
match self {
SubMsP99Source::Local => "local",
SubMsP99Source::Fleet => "fleet",
}
}
pub fn from_wire(s: &str) -> Self {
match s {
"fleet" => SubMsP99Source::Fleet,
_ => SubMsP99Source::Local,
}
}
pub fn from_env() -> (Self, Option<String>) {
match std::env::var("SUBMS_FLEET_INSTANCE") {
Ok(id) if !id.trim().is_empty() => (SubMsP99Source::Fleet, Some(id.trim().to_string())),
_ => (SubMsP99Source::Local, None),
}
}
}
pub struct SubMsFeatureManifest {
root: Json,
run_source: Option<(SubMsP99Source, Option<String>)>,
}
impl SubMsFeatureManifest {
pub fn new(lang: &str) -> Self {
SubMsFeatureManifest {
run_source: None,
root: Json::Obj(vec![
("lang".to_string(), Json::Str(lang.to_string())),
("features".to_string(), Json::Obj(Vec::new())),
]),
}
}
pub fn load_str(lang: &str, text: &str) -> Self {
let trimmed = text.trim();
if trimmed.is_empty() {
return Self::new(lang);
}
match parse_json(trimmed) {
Ok(root @ Json::Obj(_)) => {
let mut m = SubMsFeatureManifest {
root,
run_source: None,
};
m.ensure_features_obj();
m
}
_ => Self::new(lang),
}
}
pub fn set_p99_source(&mut self, source: SubMsP99Source, reference: Option<&str>) {
self.run_source = Some((source, reference.map(|r| r.to_string())));
let root = match self.root.as_object_mut() {
Some(r) => r,
None => return,
};
Json::set(root, "p99_source", Json::Str(source.as_str().to_string()));
match (source, reference) {
(SubMsP99Source::Fleet, Some(r)) if !r.is_empty() => {
Json::set(root, "p99_source_ref", Json::Str(r.to_string()))
}
_ => Json::remove(root, "p99_source_ref"),
}
}
pub fn p99_source(&self) -> SubMsP99Source {
match self.root.get("p99_source") {
Some(Json::Str(s)) => SubMsP99Source::from_wire(s),
_ => SubMsP99Source::Local,
}
}
pub fn p99_source_ref(&self) -> Option<&str> {
match self.root.get("p99_source_ref") {
Some(Json::Str(s)) => Some(s.as_str()),
_ => None,
}
}
fn ensure_features_obj(&mut self) {
if let Json::Obj(root) = &mut self.root {
let has = root
.iter()
.any(|(k, v)| k == "features" && matches!(v, Json::Obj(_)));
if !has {
Json::set(root, "features", Json::Obj(Vec::new()));
}
}
}
pub fn set_feature(
&mut self,
name: &str,
category: SubMsFeatureCategory,
p99_by_stage: &BTreeMap<String, u64>,
reason: &str,
) {
let root = match self.root.as_object_mut() {
Some(r) => r,
None => return,
};
if Json::get_mut(root, "features").is_none() {
Json::set(root, "features", Json::Obj(Vec::new()));
}
let features = match Json::get_mut(root, "features").and_then(Json::as_object_mut) {
Some(f) => f,
None => return,
};
if Json::get_mut(features, name).is_none() {
Json::set(features, name, Json::Obj(Vec::new()));
}
let entry = match Json::get_mut(features, name).and_then(Json::as_object_mut) {
Some(e) => e,
None => return,
};
Json::set(entry, "perf", Json::Str(category.as_str().to_string()));
Json::set(entry, "perfReason", Json::Str(reason.to_string()));
if p99_by_stage.is_empty() {
entry.retain(|(k, _)| k != "p99ByStage");
} else {
let stages: Vec<(String, Json)> = p99_by_stage
.iter()
.map(|(k, v)| (k.clone(), Json::Num(v.to_string())))
.collect();
Json::set(entry, "p99ByStage", Json::Obj(stages));
}
match &self.run_source {
Some((source, reference)) => {
Json::set(entry, "p99Source", Json::Str(source.as_str().to_string()));
match (source, reference) {
(SubMsP99Source::Fleet, Some(r)) if !r.is_empty() => {
Json::set(entry, "p99SourceRef", Json::Str(r.clone()))
}
_ => Json::remove(entry, "p99SourceRef"),
}
}
None => {
Json::remove(entry, "p99Source");
Json::remove(entry, "p99SourceRef");
}
}
}
pub fn set_feature_stages(
&mut self,
name: &str,
stages: &BTreeMap<String, SubMsStageClass>,
reason: &str,
) {
let rolled = roll_up_stages(stages);
let flat: BTreeMap<String, u64> =
stages.iter().map(|(k, v)| (k.clone(), v.p99_ns)).collect();
self.set_feature(name, rolled, &flat, reason);
let root = match self.root.as_object_mut() {
Some(r) => r,
None => return,
};
let features = match Json::get_mut(root, "features").and_then(Json::as_object_mut) {
Some(f) => f,
None => return,
};
let entry = match Json::get_mut(features, name).and_then(Json::as_object_mut) {
Some(e) => e,
None => return,
};
let rows: Vec<(String, Json)> = stages
.iter()
.map(|(k, v)| {
(
k.clone(),
Json::Obj(vec![
("p99".to_string(), Json::Num(v.p99_ns.to_string())),
(
"perf".to_string(),
Json::Str(v.category.as_str().to_string()),
),
("perfReason".to_string(), Json::Str(v.reason.clone())),
]),
)
})
.collect();
if rows.is_empty() {
Json::remove(entry, "stages");
} else {
Json::set(entry, "stages", Json::Obj(rows));
}
}
pub fn stage_category(&self, feature: &str, stage: &str) -> Option<SubMsFeatureCategory> {
let v = self
.root
.get("features")?
.get(feature)?
.get("stages")?
.get(stage)?
.get("perf")?;
match v {
Json::Str(s) => SubMsFeatureCategory::from_wire(s),
_ => None,
}
}
pub fn feature_p99_source(&self, name: &str) -> Option<SubMsP99Source> {
fn text(v: Option<&Json>) -> Option<&str> {
match v {
Some(Json::Str(s)) => Some(s.as_str()),
_ => None,
}
}
let entry = self.root.get("features").and_then(|f| f.get(name));
if let Some(s) = text(entry.and_then(|e| e.get("p99Source"))) {
return Some(SubMsP99Source::from_wire(s));
}
let any_stamped = self
.root
.get("features")
.and_then(|f| match f {
Json::Obj(rows) => Some(rows),
_ => None,
})
.is_some_and(|rows| rows.iter().any(|(_, v)| v.get("p99Source").is_some()));
if any_stamped {
return None;
}
text(self.root.get("p99_source")).map(SubMsP99Source::from_wire)
}
pub fn category_of(&self, name: &str) -> Option<SubMsFeatureCategory> {
let root = match &self.root {
Json::Obj(r) => r,
_ => return None,
};
let features = root
.iter()
.find(|(k, _)| k == "features")
.and_then(|(_, v)| match v {
Json::Obj(f) => Some(f),
_ => None,
})?;
let entry = features
.iter()
.find(|(k, _)| k == name)
.and_then(|(_, v)| match v {
Json::Obj(e) => Some(e),
_ => None,
})?;
entry
.iter()
.find(|(k, _)| k == "perf")
.and_then(|(_, v)| match v {
Json::Str(s) => SubMsFeatureCategory::from_wire(s),
_ => None,
})
}
pub fn to_json(&self) -> String {
self.root.to_pretty()
}
pub fn load(lang: &str, path: &std::path::Path) -> Self {
let text = std::fs::read_to_string(path).unwrap_or_default();
Self::load_str(lang, &text)
}
pub fn save(&self, path: &std::path::Path) -> std::io::Result<()> {
if let Some(dir) = path.parent() {
std::fs::create_dir_all(dir)?;
}
std::fs::write(path, self.to_json())
}
}
#[cfg(test)]
#[path = "feature_tests.rs"]
mod tests;