mirror of
https://github.com/nushell/nushell.git
synced 2025-08-17 21:11:10 +02:00
Copy-on-write for record values (#12305)
# Description This adds a `SharedCow` type as a transparent copy-on-write pointer that clones to unique on mutate. As an initial test, the `Record` within `Value::Record` is shared. There are some pretty big wins for performance. I'll post benchmark results in a comment. The biggest winner is nested access, as that would have cloned the records for each cell path follow before and it doesn't have to anymore. The reusability of the `SharedCow` type is nice and I think it could be used to clean up the previous work I did with `Arc` in `EngineState`. It's meant to be a mostly transparent clone-on-write that just clones on `.to_mut()` or `.into_owned()` if there are actually multiple references, but avoids cloning if the reference is unique. # User-Facing Changes - `Value::Record` field is a different type (plugin authors) # Tests + Formatting - 🟢 `toolkit fmt` - 🟢 `toolkit clippy` - 🟢 `toolkit test` - 🟢 `toolkit test stdlib` # After Submitting - [ ] use for `EngineState` - [ ] use for `Value::List`
This commit is contained in:
@ -16,7 +16,7 @@ pub fn try_build_table(
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::List { vals, .. } => try_build_list(vals, ctrlc, config, span, style_computer),
|
||||
Value::Record { val, .. } => try_build_map(*val, span, style_computer, ctrlc, config),
|
||||
Value::Record { val, .. } => try_build_map(&val, span, style_computer, ctrlc, config),
|
||||
val if matches!(val, Value::String { .. }) => {
|
||||
nu_value_to_string_clean(&val, config, style_computer).0
|
||||
}
|
||||
@ -25,7 +25,7 @@ pub fn try_build_table(
|
||||
}
|
||||
|
||||
fn try_build_map(
|
||||
record: Record,
|
||||
record: &Record,
|
||||
span: Span,
|
||||
style_computer: &StyleComputer,
|
||||
ctrlc: Option<Arc<AtomicBool>>,
|
||||
@ -42,11 +42,11 @@ fn try_build_map(
|
||||
0,
|
||||
false,
|
||||
);
|
||||
let result = ExpandedTable::new(None, false, String::new()).build_map(&record, opts);
|
||||
let result = ExpandedTable::new(None, false, String::new()).build_map(record, opts);
|
||||
match result {
|
||||
Ok(Some(result)) => result,
|
||||
Ok(None) | Err(_) => {
|
||||
nu_value_to_string(&Value::record(record, span), config, style_computer).0
|
||||
nu_value_to_string(&Value::record(record.clone(), span), config, style_computer).0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ pub fn collect_input(value: Value) -> (Vec<String>, Vec<Vec<Value>>) {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Record { val: record, .. } => {
|
||||
let (key, val) = record.into_iter().unzip();
|
||||
let (key, val) = record.into_owned().into_iter().unzip();
|
||||
(key, vec![val])
|
||||
}
|
||||
Value::List { vals, .. } => {
|
||||
|
@ -1038,7 +1038,7 @@ fn set_config(hm: &mut HashMap<String, Value>, path: &[&str], value: Value) -> b
|
||||
if path.len() == 2 {
|
||||
let key = path[1];
|
||||
|
||||
record.insert(key, value);
|
||||
record.to_mut().insert(key, value);
|
||||
} else {
|
||||
let mut hm2: HashMap<String, Value> = HashMap::new();
|
||||
for (k, v) in record.iter() {
|
||||
|
Reference in New Issue
Block a user