@@ -204,8 +204,10 @@ pub struct ValueIterMut<'a, T> {
204204/// An drain iterator of all values associated with a single header name.
205205#[ derive( Debug ) ]
206206pub struct ValueDrain < ' a , T > {
207+ raw_links : RawLinks < T > ,
208+ extra_values : * mut Vec < ExtraValue < T > > ,
207209 first : Option < T > ,
208- next : Option < :: std :: vec :: IntoIter < T > > ,
210+ next : Option < usize > ,
209211 lt : PhantomData < & ' a mut HeaderMap < T > > ,
210212}
211213
@@ -1190,16 +1192,13 @@ impl<T> HeaderMap<T> {
11901192 }
11911193
11921194 let raw_links = self . raw_links ( ) ;
1193- let extra_values = & mut self . extra_values ;
1194-
1195- let next = links. map ( |l| {
1196- drain_all_extra_values ( raw_links, extra_values, l. next )
1197- . into_iter ( )
1198- } ) ;
1195+ let extra_values = & mut self . extra_values as * mut _ ;
11991196
12001197 ValueDrain {
1198+ raw_links,
1199+ extra_values,
12011200 first : Some ( old) ,
1202- next : next,
1201+ next : links . map ( |l| l . next ) ,
12031202 lt : PhantomData ,
12041203 }
12051204 }
@@ -1702,22 +1701,6 @@ fn remove_extra_value<T>(mut raw_links: RawLinks<T>, extra_values: &mut Vec<Extr
17021701 extra
17031702}
17041703
1705-
1706- fn drain_all_extra_values < T > ( raw_links : RawLinks < T > , extra_values : & mut Vec < ExtraValue < T > > , mut head : usize ) -> Vec < T > {
1707- let mut vec = Vec :: new ( ) ;
1708- loop {
1709- let extra = remove_extra_value ( raw_links, extra_values, head) ;
1710- vec. push ( extra. value ) ;
1711-
1712- if let Link :: Extra ( idx) = extra. next {
1713- head = idx;
1714- } else {
1715- break ;
1716- }
1717- }
1718- vec
1719- }
1720-
17211704impl < ' a , T > IntoIterator for & ' a HeaderMap < T > {
17221705 type Item = ( & ' a HeaderName , & ' a T ) ;
17231706 type IntoIter = Iter < ' a , T > ;
@@ -2203,17 +2186,17 @@ impl<'a, T> Iterator for Drain<'a, T> {
22032186 // Read the header name
22042187 key = ptr:: read ( & entry. key as * const _ ) ;
22052188 value = ptr:: read ( & entry. value as * const _ ) ;
2189+ next = entry. links . map ( |l| l. next ) ;
2190+
22062191
22072192 let raw_links = RawLinks ( self . entries ) ;
2208- let extra_values = & mut * self . extra_values ;
2209- next = entry. links . map ( |l| {
2210- drain_all_extra_values ( raw_links, extra_values, l. next )
2211- . into_iter ( )
2212- } ) ;
2193+ let extra_values = self . extra_values ;
22132194
22142195 ValueDrain {
2196+ raw_links,
2197+ extra_values,
22152198 first : Some ( value) ,
2216- next,
2199+ next : next ,
22172200 lt : PhantomData ,
22182201 }
22192202 } ;
@@ -2947,15 +2930,12 @@ impl<'a, T> OccupiedEntry<'a, T> {
29472930 pub fn remove_entry_mult ( self ) -> ( HeaderName , ValueDrain < ' a , T > ) {
29482931 let entry = self . map . remove_found ( self . probe , self . index ) ;
29492932 let raw_links = self . map . raw_links ( ) ;
2950- let extra_values = & mut self . map . extra_values ;
2951-
2952- let next = entry. links . map ( |l| {
2953- drain_all_extra_values ( raw_links, extra_values, l. next )
2954- . into_iter ( )
2955- } ) ;
2933+ let extra_values = & mut self . map . extra_values as * mut _ ;
29562934 let drain = ValueDrain {
2935+ raw_links,
2936+ extra_values,
29572937 first : Some ( entry. value ) ,
2958- next,
2938+ next : entry . links . map ( |l| l . next ) ,
29592939 lt : PhantomData ,
29602940 } ;
29612941 ( entry. key , drain)
@@ -3048,26 +3028,31 @@ impl<'a, T> Iterator for ValueDrain<'a, T> {
30483028 fn next ( & mut self ) -> Option < T > {
30493029 if self . first . is_some ( ) {
30503030 self . first . take ( )
3051- } else if let Some ( ref mut extras) = self . next {
3052- extras. next ( )
3031+ } else if let Some ( next) = self . next {
3032+ // Remove the extra value
3033+ let extra = unsafe {
3034+ remove_extra_value ( self . raw_links , & mut * self . extra_values , next)
3035+ } ;
3036+
3037+ match extra. next {
3038+ Link :: Extra ( idx) => self . next = Some ( idx) ,
3039+ Link :: Entry ( _) => self . next = None ,
3040+ }
3041+
3042+ Some ( extra. value )
30533043 } else {
30543044 None
30553045 }
30563046 }
30573047
30583048 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
3059- match ( & self . first , & self . next ) {
3049+ match ( & self . first , self . next ) {
30603050 // Exactly 1
3061- ( & Some ( _) , & None ) => ( 1 , Some ( 1 ) ) ,
3062- // 1 + extras
3063- ( & Some ( _) , & Some ( ref extras) ) => {
3064- let ( l, u) = extras. size_hint ( ) ;
3065- ( l + 1 , u. map ( |u| u + 1 ) )
3066- } ,
3067- // Extras only
3068- ( & None , & Some ( ref extras) ) => extras. size_hint ( ) ,
3051+ ( & Some ( _) , None ) => ( 1 , Some ( 1 ) ) ,
3052+ // At least 1
3053+ ( & _, Some ( _) ) => ( 1 , None ) ,
30693054 // No more
3070- ( & None , & None ) => ( 0 , Some ( 0 ) ) ,
3055+ ( & None , None ) => ( 0 , Some ( 0 ) ) ,
30713056 }
30723057 }
30733058}
0 commit comments