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() { | ||||
|             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()?; | ||||
|         if right_set.is_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(); | ||||
| 
 | ||||
|         // Both iterators have at least one entry
 | ||||
|         let mut left = left_keys.next().unwrap(); | ||||
|         let mut right = right_keys.next().unwrap(); | ||||
|         let mut left = left_iter.next().unwrap(); | ||||
|         let mut right = right_iter.next().unwrap(); | ||||
| 
 | ||||
|         // Calculate the intersection of two attribute sets by iterating them
 | ||||
|         // 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
 | ||||
|         // heavy use of this function in nixpkgs.
 | ||||
|         loop { | ||||
|             if left == right { | ||||
|                 // We know that the key exists in the set, and can
 | ||||
|                 // skip the check instructions.
 | ||||
|                 unsafe { | ||||
|                     out.insert( | ||||
|                         right.clone(), | ||||
|                         right_set.select(right).unwrap_unchecked().clone(), | ||||
|                     ); | ||||
|                 } | ||||
|             if left.0 == right.0 { | ||||
|                 out.insert(right.0.clone(), right.1.clone()); | ||||
| 
 | ||||
|                 left = match left_keys.next() { | ||||
|                 left = match left_iter.next() { | ||||
|                     Some(x) => x, | ||||
|                     None => break, | ||||
|                 }; | ||||
| 
 | ||||
|                 right = match right_keys.next() { | ||||
|                 right = match right_iter.next() { | ||||
|                     Some(x) => x, | ||||
|                     None => break, | ||||
|                 }; | ||||
|  | @ -834,16 +827,16 @@ mod pure_builtins { | |||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             if left < right { | ||||
|                 left = match left_keys.next() { | ||||
|             if left.0 < right.0 { | ||||
|                 left = match left_iter.next() { | ||||
|                     Some(x) => x, | ||||
|                     None => break, | ||||
|                 }; | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             if right < left { | ||||
|                 right = match right_keys.next() { | ||||
|             if right.0 < left.0 { | ||||
|                 right = match right_iter.next() { | ||||
|                     Some(x) => x, | ||||
|                     None => break, | ||||
|                 }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue