perf(headers): use a Vec instead of HashMap internally
This commit is contained in:
		| @@ -1,4 +1,6 @@ | ||||
| pub use self::item::Item; | ||||
| pub use self::vec_map::{VecMap, Entry}; | ||||
|  | ||||
| mod cell; | ||||
| mod item; | ||||
| mod vec_map; | ||||
|   | ||||
							
								
								
									
										89
									
								
								src/header/internals/vec_map.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/header/internals/vec_map.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| #[derive(Clone)] | ||||
| pub struct VecMap<K, V> { | ||||
|     vec: Vec<(K, V)>, | ||||
| } | ||||
|  | ||||
| impl<K: PartialEq, V> VecMap<K, V> { | ||||
|     pub fn new() -> VecMap<K, V> { | ||||
|         VecMap { | ||||
|             vec: Vec::new() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn insert(&mut self, key: K, value: V) { | ||||
|         match self.find(&key) { | ||||
|             Some(pos) => self.vec[pos] = (key, value), | ||||
|             None => self.vec.push((key, value)) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn entry(&mut self, key: K) -> Entry<K, V> { | ||||
|         match self.find(&key) { | ||||
|             Some(pos) => Entry::Occupied(OccupiedEntry { | ||||
|                 vec: self, | ||||
|                 pos: pos, | ||||
|             }), | ||||
|             None => Entry::Vacant(VacantEntry { | ||||
|                 vec: self, | ||||
|                 key: key, | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn get(&self, key: &K) -> Option<&V> { | ||||
|         self.find(key).map(move |pos| &self.vec[pos].1) | ||||
|     } | ||||
|  | ||||
|     pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { | ||||
|         self.find(key).map(move |pos| &mut self.vec[pos].1) | ||||
|     } | ||||
|  | ||||
|     pub fn contains_key(&self, key: &K) -> bool { | ||||
|         self.find(key).is_some() | ||||
|     } | ||||
|  | ||||
|     pub fn len(&self) -> usize { self.vec.len() } | ||||
|     pub fn iter(&self) -> ::std::slice::Iter<(K, V)> { | ||||
|         self.vec.iter() | ||||
|     } | ||||
|     pub fn remove(&mut self, key: &K) -> Option<V> { | ||||
|         self.find(key).map(|pos| self.vec.remove(pos)).map(|(_, v)| v) | ||||
|     } | ||||
|     pub fn clear(&mut self) { | ||||
|         self.vec.clear(); | ||||
|     } | ||||
|  | ||||
|     fn find(&self, key: &K) -> Option<usize> { | ||||
|         self.vec.iter().position(|entry| key == &entry.0) | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub enum Entry<'a, K: 'a, V: 'a> { | ||||
|     Vacant(VacantEntry<'a, K, V>), | ||||
|     Occupied(OccupiedEntry<'a, K, V>) | ||||
| } | ||||
|  | ||||
| pub struct VacantEntry<'a, K: 'a, V: 'a> { | ||||
|     vec: &'a mut VecMap<K, V>, | ||||
|     key: K, | ||||
| } | ||||
|  | ||||
| impl<'a, K, V> VacantEntry<'a, K, V> { | ||||
|     pub fn insert(self, val: V) -> &'a mut V { | ||||
|         let mut vec = self.vec; | ||||
|         vec.vec.push((self.key, val)); | ||||
|         let pos = vec.vec.len() - 1; | ||||
|         &mut vec.vec[pos].1 | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub struct OccupiedEntry<'a, K: 'a, V: 'a> { | ||||
|     vec: &'a mut VecMap<K, V>, | ||||
|     pos: usize, | ||||
| } | ||||
|  | ||||
| impl<'a, K, V> OccupiedEntry<'a, K, V> { | ||||
|     pub fn into_mut(self) -> &'a mut V { | ||||
|         &mut self.vec.vec[self.pos].1 | ||||
|     } | ||||
| } | ||||
| @@ -77,8 +77,8 @@ | ||||
| //! ``` | ||||
| use std::any::Any; | ||||
| use std::borrow::{Cow, ToOwned}; | ||||
| use std::collections::HashMap; | ||||
| use std::collections::hash_map::{Iter, Entry}; | ||||
| //use std::collections::HashMap; | ||||
| //use std::collections::hash_map::{Iter, Entry}; | ||||
| use std::iter::{FromIterator, IntoIterator}; | ||||
| use std::ops::{Deref, DerefMut}; | ||||
| use std::{mem, fmt}; | ||||
| @@ -87,7 +87,7 @@ use {httparse, traitobject}; | ||||
| use typeable::Typeable; | ||||
| use unicase::UniCase; | ||||
|  | ||||
| use self::internals::Item; | ||||
| use self::internals::{Item, VecMap, Entry}; | ||||
|  | ||||
| #[cfg(feature = "serde-serialization")] | ||||
| use serde::{Deserialize, Deserializer, Serialize, Serializer}; | ||||
| @@ -169,7 +169,8 @@ fn header_name<T: Header>() -> &'static str { | ||||
| /// A map of header fields on requests and responses. | ||||
| #[derive(Clone)] | ||||
| pub struct Headers { | ||||
|     data: HashMap<HeaderName, Item> | ||||
|     //data: HashMap<HeaderName, Item> | ||||
|     data: VecMap<HeaderName, Item>, | ||||
| } | ||||
|  | ||||
| impl Default for Headers { | ||||
| @@ -183,7 +184,7 @@ impl Headers { | ||||
|     /// Creates a new, empty headers map. | ||||
|     pub fn new() -> Headers { | ||||
|         Headers { | ||||
|             data: HashMap::new() | ||||
|             data: VecMap::new() | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -377,14 +378,14 @@ impl Deserialize for Headers { | ||||
| /// An `Iterator` over the fields in a `Headers` map. | ||||
| #[allow(missing_debug_implementations)] | ||||
| pub struct HeadersItems<'a> { | ||||
|     inner: Iter<'a, HeaderName, Item> | ||||
|     inner: ::std::slice::Iter<'a, (HeaderName, Item)> | ||||
| } | ||||
|  | ||||
| impl<'a> Iterator for HeadersItems<'a> { | ||||
|     type Item = HeaderView<'a>; | ||||
|  | ||||
|     fn next(&mut self) -> Option<HeaderView<'a>> { | ||||
|         self.inner.next().map(|(k, v)| HeaderView(k, v)) | ||||
|         self.inner.next().map(|&(ref k, ref v)| HeaderView(k, v)) | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user