mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 22:50:14 +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:
@ -58,7 +58,7 @@ fn horizontal_rotate_value(
|
||||
Value::Record { val: record, .. } => {
|
||||
let rotations = by.map(|n| n % record.len()).unwrap_or(1);
|
||||
|
||||
let (mut cols, mut vals): (Vec<_>, Vec<_>) = record.into_iter().unzip();
|
||||
let (mut cols, mut vals): (Vec<_>, Vec<_>) = record.into_owned().into_iter().unzip();
|
||||
if !cells_only {
|
||||
match direction {
|
||||
HorizontalDirection::Right => cols.rotate_right(rotations),
|
||||
|
@ -171,7 +171,7 @@ pub fn rotate(
|
||||
let span = val.span();
|
||||
match val {
|
||||
Value::Record { val: record, .. } => {
|
||||
let (cols, vals): (Vec<_>, Vec<_>) = record.into_iter().unzip();
|
||||
let (cols, vals): (Vec<_>, Vec<_>) = record.into_owned().into_iter().unzip();
|
||||
old_column_names = cols;
|
||||
new_values.extend_from_slice(&vals);
|
||||
}
|
||||
|
@ -154,7 +154,8 @@ impl Iterator for UpdateCellIterator {
|
||||
let span = val.span();
|
||||
match val {
|
||||
Value::Record { val, .. } => Some(Value::record(
|
||||
val.into_iter()
|
||||
val.into_owned()
|
||||
.into_iter()
|
||||
.map(|(col, val)| match &self.columns {
|
||||
Some(cols) if !cols.contains(&col) => (col, val),
|
||||
_ => (
|
||||
|
Reference in New Issue
Block a user