Move to custom stream storage
This commit is contained in:
		| @@ -1,16 +1,16 @@ | ||||
| mod recv; | ||||
| mod send; | ||||
| mod store; | ||||
|  | ||||
| use self::recv::Recv; | ||||
| use self::send::Send; | ||||
| use self::store::{Store, Entry}; | ||||
|  | ||||
| use {frame, Peer, StreamId, ConnectionError}; | ||||
| use proto::*; | ||||
| use error::Reason::*; | ||||
| use error::User::*; | ||||
|  | ||||
| use ordermap::{OrderMap, Entry}; | ||||
|  | ||||
| // TODO: All the VecDeques should become linked lists using the state::Stream | ||||
| // values. | ||||
| #[derive(Debug)] | ||||
| @@ -19,11 +19,9 @@ pub struct Streams<P> { | ||||
|     inner: Inner<P>, | ||||
|  | ||||
|     /// Streams | ||||
|     streams: StreamMap, | ||||
|     streams: Store, | ||||
| } | ||||
|  | ||||
| type StreamMap = OrderMap<StreamId, state::Stream>; | ||||
|  | ||||
| /// Fields needed to manage state related to managing the set of streams. This | ||||
| /// is mostly split out to make ownership happy. | ||||
| /// | ||||
| @@ -59,7 +57,7 @@ impl<P: Peer> Streams<P> { | ||||
|                 recv: Recv::new(&config), | ||||
|                 send: Send::new(&config), | ||||
|             }, | ||||
|             streams: OrderMap::default(), | ||||
|             streams: Store::new(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| use {frame, Peer, ConnectionError}; | ||||
| use proto::*; | ||||
| use super::{Config, StreamMap}; | ||||
| use super::{Config, Store}; | ||||
|  | ||||
| use error::Reason::*; | ||||
|  | ||||
| @@ -201,7 +201,7 @@ impl<P: Peer> Recv<P> { | ||||
|  | ||||
|     /// Send stream level window update | ||||
|     pub fn send_stream_window_update<T, B>(&mut self, | ||||
|                                            streams: &mut StreamMap, | ||||
|                                            streams: &mut Store, | ||||
|                                            dst: &mut Codec<T, B>) | ||||
|         -> Poll<(), ConnectionError> | ||||
|         where T: AsyncWrite, | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| use {frame, Peer, ConnectionError}; | ||||
| use proto::*; | ||||
| use super::{Config, StreamMap}; | ||||
| use super::{Config, Store}; | ||||
|  | ||||
| use error::User::*; | ||||
|  | ||||
| @@ -125,7 +125,7 @@ impl<P: Peer> Send<P> { | ||||
|     } | ||||
|  | ||||
|     /// Get pending window updates | ||||
|     pub fn poll_window_update(&mut self, streams: &mut StreamMap) | ||||
|     pub fn poll_window_update(&mut self, streams: &mut Store) | ||||
|         -> Poll<WindowUpdate, ConnectionError> | ||||
|     { | ||||
|         // This biases connection window updates, which probably makes sense. | ||||
|   | ||||
							
								
								
									
										81
									
								
								src/proto/streams/store.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								src/proto/streams/store.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| extern crate slab; | ||||
|  | ||||
| use proto::*; | ||||
|  | ||||
| use std::collections::{HashMap, hash_map}; | ||||
|  | ||||
| /// Storage for streams | ||||
| #[derive(Debug)] | ||||
| pub struct Store { | ||||
|     slab: slab::Slab<state::Stream>, | ||||
|     ids: HashMap<StreamId, usize>, | ||||
| } | ||||
|  | ||||
| pub enum Entry<'a> { | ||||
|     Occupied(OccupiedEntry<'a>), | ||||
|     Vacant(VacantEntry<'a>), | ||||
| } | ||||
|  | ||||
| pub struct OccupiedEntry<'a> { | ||||
|     ids: hash_map::OccupiedEntry<'a, StreamId, usize>, | ||||
|     slab: &'a mut slab::Slab<state::Stream>, | ||||
| } | ||||
|  | ||||
| pub struct VacantEntry<'a> { | ||||
|     ids: hash_map::VacantEntry<'a, StreamId, usize>, | ||||
|     slab: &'a mut slab::Slab<state::Stream>, | ||||
| } | ||||
|  | ||||
| impl Store { | ||||
|     pub fn new() -> Self { | ||||
|         Store { | ||||
|             slab: slab::Slab::new(), | ||||
|             ids: HashMap::new(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn get_mut(&mut self, id: &StreamId) -> Option<&mut state::Stream> { | ||||
|         if let Some(handle) = self.ids.get(id) { | ||||
|             Some(&mut self.slab[*handle]) | ||||
|         } else { | ||||
|             None | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn entry(&mut self, id: StreamId) -> Entry { | ||||
|         use self::hash_map::Entry::*; | ||||
|  | ||||
|         match self.ids.entry(id) { | ||||
|             Occupied(e) => { | ||||
|                 Entry::Occupied(OccupiedEntry { | ||||
|                     ids: e, | ||||
|                     slab: &mut self.slab, | ||||
|                 }) | ||||
|             } | ||||
|             Vacant(e) => { | ||||
|                 Entry::Vacant(VacantEntry { | ||||
|                     ids: e, | ||||
|                     slab: &mut self.slab, | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> OccupiedEntry<'a> { | ||||
|     pub fn into_mut(self) -> &'a mut state::Stream { | ||||
|         &mut self.slab[*self.ids.get()] | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<'a> VacantEntry<'a> { | ||||
|     pub fn insert(self, value: state::Stream) -> &'a mut state::Stream { | ||||
|         // Insert the value in the slab | ||||
|         let handle = self.slab.insert(value); | ||||
|  | ||||
|         // Insert the handle in the ID map | ||||
|         self.ids.insert(handle); | ||||
|  | ||||
|         &mut self.slab[handle] | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user