Optimize replace_headers to avoid copies of keys
				
					
				
			Sometimes, I'm amazed at what non lexical lifetimes allows.
This commit is contained in:
		
				
					committed by
					
						 Sean McArthur
						Sean McArthur
					
				
			
			
				
	
			
			
			
						parent
						
							2881354c90
						
					
				
				
					commit
					2767071cac
				
			
							
								
								
									
										26
									
								
								src/util.rs
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/util.rs
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| use crate::header::HeaderMap; | ||||
| use crate::header::{Entry, HeaderMap, OccupiedEntry}; | ||||
|  | ||||
| // xor-shift | ||||
| #[cfg(not(target_arch = "wasm32"))] | ||||
| @@ -42,21 +42,23 @@ pub(crate) fn replace_headers(dst: &mut HeaderMap, src: HeaderMap) { | ||||
|     // The first time a name is yielded, it will be Some(name), and if | ||||
|     // there are more values with the same name, the next yield will be | ||||
|     // None. | ||||
|     // | ||||
|     // TODO: a complex exercise would be to optimize this to only | ||||
|     // require 1 hash/lookup of the key, but doing something fancy | ||||
|     // with header::Entry... | ||||
|  | ||||
|     let mut prev_name = None; | ||||
|     let mut prev_entry: Option<OccupiedEntry<_>> = None; | ||||
|     for (key, value) in src { | ||||
|         match key { | ||||
|             Some(key) => { | ||||
|                 dst.insert(key.clone(), value); | ||||
|                 prev_name = Some(key); | ||||
|             Some(key) => match dst.entry(key) { | ||||
|                 Entry::Occupied(mut e) => { | ||||
|                     e.insert(value); | ||||
|                     prev_entry = Some(e); | ||||
|                 } | ||||
|             None => match prev_name { | ||||
|                 Some(ref key) => { | ||||
|                     dst.append(key.clone(), value); | ||||
|                 Entry::Vacant(e) => { | ||||
|                     let e = e.insert_entry(value); | ||||
|                     prev_entry = Some(e); | ||||
|                 } | ||||
|             }, | ||||
|             None => match prev_entry { | ||||
|                 Some(ref mut entry) => { | ||||
|                     entry.append(value); | ||||
|                 } | ||||
|                 None => unreachable!("HeaderMap::into_iter yielded None first"), | ||||
|             }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user