refactor(eval/builtins/intersectAttrs): use kv iterator instead of unsafe get
We can just iterate key-value pairs for our merge sort, rather than relying on unsafe to get us the value without costing us a presence check. Change-Id: I7145a1b2f33a8510de8d7fbd1a12804517a78042 Reviewed-on: https://cl.snix.dev/c/snix/+/30371 Tested-by: besadii Reviewed-by: Florian Klink <flokli@flokli.de>
This commit is contained in:
parent
94ba112360
commit
3d95109328
1 changed files with 12 additions and 19 deletions
|
|
@ -789,19 +789,19 @@ mod pure_builtins {
|
||||||
if left_set.is_empty() {
|
if left_set.is_empty() {
|
||||||
return Ok(Value::attrs(NixAttrs::empty()));
|
return Ok(Value::attrs(NixAttrs::empty()));
|
||||||
}
|
}
|
||||||
let mut left_keys = left_set.keys_sorted();
|
let mut left_iter = left_set.iter_sorted();
|
||||||
|
|
||||||
let right_set = y.to_attrs()?;
|
let right_set = y.to_attrs()?;
|
||||||
if right_set.is_empty() {
|
if right_set.is_empty() {
|
||||||
return Ok(Value::attrs(NixAttrs::empty()));
|
return Ok(Value::attrs(NixAttrs::empty()));
|
||||||
}
|
}
|
||||||
let mut right_keys = right_set.keys_sorted();
|
let mut right_iter = right_set.iter_sorted();
|
||||||
|
|
||||||
let mut out: BTreeMap<NixString, Value> = BTreeMap::new();
|
let mut out: BTreeMap<NixString, Value> = BTreeMap::new();
|
||||||
|
|
||||||
// Both iterators have at least one entry
|
// Both iterators have at least one entry
|
||||||
let mut left = left_keys.next().unwrap();
|
let mut left = left_iter.next().unwrap();
|
||||||
let mut right = right_keys.next().unwrap();
|
let mut right = right_iter.next().unwrap();
|
||||||
|
|
||||||
// Calculate the intersection of two attribute sets by iterating them
|
// Calculate the intersection of two attribute sets by iterating them
|
||||||
// simultaneously in lexicographic order, similar to a merge sort.
|
// simultaneously in lexicographic order, similar to a merge sort.
|
||||||
|
|
@ -811,22 +811,15 @@ mod pure_builtins {
|
||||||
// We opted for this implementation over simpler ones because of the
|
// We opted for this implementation over simpler ones because of the
|
||||||
// heavy use of this function in nixpkgs.
|
// heavy use of this function in nixpkgs.
|
||||||
loop {
|
loop {
|
||||||
if left == right {
|
if left.0 == right.0 {
|
||||||
// We know that the key exists in the set, and can
|
out.insert(right.0.clone(), right.1.clone());
|
||||||
// skip the check instructions.
|
|
||||||
unsafe {
|
|
||||||
out.insert(
|
|
||||||
right.clone(),
|
|
||||||
right_set.select(right).unwrap_unchecked().clone(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
left = match left_keys.next() {
|
left = match left_iter.next() {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => break,
|
None => break,
|
||||||
};
|
};
|
||||||
|
|
||||||
right = match right_keys.next() {
|
right = match right_iter.next() {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => break,
|
None => break,
|
||||||
};
|
};
|
||||||
|
|
@ -834,16 +827,16 @@ mod pure_builtins {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if left < right {
|
if left.0 < right.0 {
|
||||||
left = match left_keys.next() {
|
left = match left_iter.next() {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => break,
|
None => break,
|
||||||
};
|
};
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if right < left {
|
if right.0 < left.0 {
|
||||||
right = match right_keys.next() {
|
right = match right_iter.next() {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => break,
|
None => break,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue