test(engine): retain static schema names across shared factor rows

This commit is contained in:
boris
2026-09-13 13:07:51 +08:00
committed by boris
parent 93809eea1b
commit 2286bfa757
2 changed files with 23 additions and 3 deletions
+13
View File
@@ -436,6 +436,19 @@ mod tests {
assert!(rows.iter().all(|row| matches!(row.storage, Storage::Owned(_)))); assert!(rows.iter().all(|row| matches!(row.storage, Storage::Owned(_))));
} }
#[test]
fn shared_schema_borrows_a_static_key_even_after_a_dynamic_equal_key() {
const KEY: &str = "a_shared_factor_name_longer_than_inline_storage";
let mut rows = (0..64).map(|index| NumericFactorMap::from([
(if index == 0 { Cow::Owned(KEY.to_string()) } else { Cow::Borrowed(KEY) }, index as f64),
(Cow::Borrowed("another"), 2.0),
])).collect::<Vec<_>>();
assert_eq!(NumericFactorMap::share_rows(rows.iter_mut()), rows.len());
for row in &rows {
assert_eq!(row.keys().find(|key| key.as_str() == KEY).unwrap().as_static_str(), Some(KEY));
}
}
#[test] #[test]
fn compact_keys_inline_dynamic_names_and_keep_long_static_storage() { fn compact_keys_inline_dynamic_names_and_keep_long_static_storage() {
const LONG: &str = "a_long_static_factor_identifier_that_must_remain_borrowed"; const LONG: &str = "a_long_static_factor_identifier_that_must_remain_borrowed";
@@ -1,4 +1,4 @@
use std::collections::BTreeSet; use std::collections::BTreeMap;
use std::sync::Arc; use std::sync::Arc;
use compact_str::CompactString; use compact_str::CompactString;
@@ -103,8 +103,15 @@ pub(super) fn share<'a>(rows: impl IntoIterator<Item = &'a mut NumericFactorMap>
let Storage::Owned(entries) = &row.storage else { return None }; let Storage::Owned(entries) = &row.storage else { return None };
sum.checked_add(entries.capacity().checked_mul(std::mem::size_of::<(CompactString, f64)>())?) sum.checked_add(entries.capacity().checked_mul(std::mem::size_of::<(CompactString, f64)>())?)
}) else { return 0 }; }) else { return 0 };
let fields = rows.iter().flat_map(|row| row.keys()).collect::<BTreeSet<_>>() let mut names = BTreeMap::<&str, &CompactString>::new();
.into_iter().cloned().collect::<Vec<_>>(); for name in rows.iter().flat_map(|row| row.keys()) {
names.entry(name.as_str()).and_modify(|existing| {
if existing.as_static_str().is_none() && name.as_static_str().is_some() {
*existing = name;
}
}).or_insert(name);
}
let fields = names.into_values().cloned().collect::<Vec<_>>();
let Some(cells) = rows.len().checked_mul(fields.len()) else { return 0 }; let Some(cells) = rows.len().checked_mul(fields.len()) else { return 0 };
if cells == 0 { if cells == 0 {
return 0; return 0;