Skip to content

Commit 0c847f7

Browse files
committed
Merge pull request #814 from hyperium/headers-vec-map
perf(headers): use a VecMap, and check name against literals
2 parents 8848049 + d80d61c commit 0c847f7

19 files changed

+210
-61
lines changed

src/header/common/access_control_allow_credentials.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ const ACCESS_CONTROL_ALLOW_CREDENTIALS_TRUE: UniCase<&'static str> = UniCase("tr
4242

4343
impl Header for AccessControlAllowCredentials {
4444
fn header_name() -> &'static str {
45-
"Access-Control-Allow-Credentials"
45+
static NAME: &'static str = "Access-Control-Allow-Credentials";
46+
NAME
4647
}
4748

4849
fn parse_header(raw: &[Vec<u8>]) -> ::Result<AccessControlAllowCredentials> {

src/header/common/authorization.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ impl<S: Scheme> DerefMut for Authorization<S> {
7373

7474
impl<S: Scheme + Any> Header for Authorization<S> where <S as FromStr>::Err: 'static {
7575
fn header_name() -> &'static str {
76-
"Authorization"
76+
static NAME: &'static str = "Authorization";
77+
NAME
7778
}
7879

7980
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Authorization<S>> {

src/header/common/cache_control.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ __hyper__deref!(CacheControl => Vec<CacheDirective>);
5151

5252
impl Header for CacheControl {
5353
fn header_name() -> &'static str {
54-
"Cache-Control"
54+
static NAME: &'static str = "Cache-Control";
55+
NAME
5556
}
5657

5758
fn parse_header(raw: &[Vec<u8>]) -> ::Result<CacheControl> {

src/header/common/content_disposition.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ pub struct ContentDisposition {
9090

9191
impl Header for ContentDisposition {
9292
fn header_name() -> &'static str {
93-
"Content-Disposition"
93+
static NAME: &'static str = "Content-Disposition";
94+
NAME
9495
}
9596

9697
fn parse_header(raw: &[Vec<u8>]) -> ::Result<ContentDisposition> {

src/header/common/content_length.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@ use header::{Header, parsing};
3232
#[derive(Clone, Copy, Debug, PartialEq)]
3333
pub struct ContentLength(pub u64);
3434

35+
//static NAME: &'static str = "Content-Length";
36+
3537
impl Header for ContentLength {
3638
#[inline]
3739
fn header_name() -> &'static str {
38-
"Content-Length"
40+
static NAME: &'static str = "Content-Length";
41+
NAME
3942
}
4043
fn parse_header(raw: &[Vec<u8>]) -> ::Result<ContentLength> {
4144
// If multiple Content-Length headers were sent, everything can still

src/header/common/cookie.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ __hyper__deref!(Cookie => Vec<CookiePair>);
3939

4040
impl Header for Cookie {
4141
fn header_name() -> &'static str {
42-
"Cookie"
42+
static NAME: &'static str = "Cookie";
43+
NAME
4344
}
4445

4546
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Cookie> {

src/header/common/expect.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ const EXPECT_CONTINUE: UniCase<&'static str> = UniCase("100-continue");
3030

3131
impl Header for Expect {
3232
fn header_name() -> &'static str {
33-
"Expect"
33+
static NAME: &'static str = "Expect";
34+
NAME
3435
}
3536

3637
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Expect> {

src/header/common/host.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ pub struct Host {
4343

4444
impl Header for Host {
4545
fn header_name() -> &'static str {
46-
"Host"
46+
static NAME: &'static str = "Host";
47+
NAME
4748
}
4849

4950
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Host> {

src/header/common/if_range.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ pub enum IfRange {
5555

5656
impl Header for IfRange {
5757
fn header_name() -> &'static str {
58-
"If-Range"
58+
static NAME: &'static str = "If-Range";
59+
NAME
5960
}
6061
fn parse_header(raw: &[Vec<u8>]) -> ::Result<IfRange> {
6162
let etag: ::Result<EntityTag> = header::parsing::from_one_raw_str(raw);

src/header/common/mod.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ macro_rules! header {
217217
__hyper__deref!($id => Vec<$item>);
218218
impl $crate::header::Header for $id {
219219
fn header_name() -> &'static str {
220-
$n
220+
static NAME: &'static str = $n;
221+
NAME
221222
}
222223
fn parse_header(raw: &[Vec<u8>]) -> $crate::Result<Self> {
223224
$crate::header::parsing::from_comma_delimited(raw).map($id)
@@ -243,7 +244,8 @@ macro_rules! header {
243244
__hyper__deref!($id => Vec<$item>);
244245
impl $crate::header::Header for $id {
245246
fn header_name() -> &'static str {
246-
$n
247+
static NAME: &'static str = $n;
248+
NAME
247249
}
248250
fn parse_header(raw: &[Vec<u8>]) -> $crate::Result<Self> {
249251
$crate::header::parsing::from_comma_delimited(raw).map($id)
@@ -268,7 +270,8 @@ macro_rules! header {
268270
__hyper__deref!($id => $value);
269271
impl $crate::header::Header for $id {
270272
fn header_name() -> &'static str {
271-
$n
273+
static NAME: &'static str = $n;
274+
NAME
272275
}
273276
fn parse_header(raw: &[Vec<u8>]) -> $crate::Result<Self> {
274277
$crate::header::parsing::from_one_raw_str(raw).map($id)
@@ -296,7 +299,8 @@ macro_rules! header {
296299
}
297300
impl $crate::header::Header for $id {
298301
fn header_name() -> &'static str {
299-
$n
302+
static NAME: &'static str = $n;
303+
NAME
300304
}
301305
fn parse_header(raw: &[Vec<u8>]) -> $crate::Result<Self> {
302306
// FIXME: Return None if no item is in $id::Only

src/header/common/pragma.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ pub enum Pragma {
4040

4141
impl Header for Pragma {
4242
fn header_name() -> &'static str {
43-
"Pragma"
43+
static NAME: &'static str = "Pragma";
44+
NAME
4445
}
4546

4647
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Pragma> {

src/header/common/prefer.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ __hyper__deref!(Prefer => Vec<Preference>);
5252

5353
impl Header for Prefer {
5454
fn header_name() -> &'static str {
55-
"Prefer"
55+
static NAME: &'static str = "Prefer";
56+
NAME
5657
}
5758

5859
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Prefer> {

src/header/common/preference_applied.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ __hyper__deref!(PreferenceApplied => Vec<Preference>);
5050

5151
impl Header for PreferenceApplied {
5252
fn header_name() -> &'static str {
53-
"Preference-Applied"
53+
static NAME: &'static str = "Preference-Applied";
54+
NAME
5455
}
5556

5657
fn parse_header(raw: &[Vec<u8>]) -> ::Result<PreferenceApplied> {

src/header/common/range.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ impl FromStr for ByteRangeSpec {
176176
impl Header for Range {
177177

178178
fn header_name() -> &'static str {
179-
"Range"
179+
static NAME: &'static str = "Range";
180+
NAME
180181
}
181182

182183
fn parse_header(raw: &[Vec<u8>]) -> ::Result<Range> {

src/header/common/set_cookie.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ __hyper__deref!(SetCookie => Vec<CookiePair>);
8484

8585
impl Header for SetCookie {
8686
fn header_name() -> &'static str {
87-
"Set-Cookie"
87+
static NAME: &'static str = "Set-Cookie";
88+
NAME
8889
}
8990

9091
fn parse_header(raw: &[Vec<u8>]) -> ::Result<SetCookie> {

src/header/common/strict_transport_security.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ impl FromStr for StrictTransportSecurity {
121121

122122
impl Header for StrictTransportSecurity {
123123
fn header_name() -> &'static str {
124-
"Strict-Transport-Security"
124+
static NAME: &'static str = "Strict-Transport-Security";
125+
NAME
125126
}
126127

127128
fn parse_header(raw: &[Vec<u8>]) -> ::Result<StrictTransportSecurity> {

src/header/internals/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
pub use self::item::Item;
2+
pub use self::vec_map::{VecMap, Entry};
23

34
mod cell;
45
mod item;
6+
mod vec_map;

src/header/internals/vec_map.rs

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#[derive(Clone)]
2+
pub struct VecMap<K, V> {
3+
vec: Vec<(K, V)>,
4+
}
5+
6+
impl<K: PartialEq, V> VecMap<K, V> {
7+
pub fn new() -> VecMap<K, V> {
8+
VecMap {
9+
vec: Vec::new()
10+
}
11+
}
12+
13+
pub fn insert(&mut self, key: K, value: V) {
14+
match self.find(&key) {
15+
Some(pos) => self.vec[pos] = (key, value),
16+
None => self.vec.push((key, value))
17+
}
18+
}
19+
20+
pub fn entry(&mut self, key: K) -> Entry<K, V> {
21+
match self.find(&key) {
22+
Some(pos) => Entry::Occupied(OccupiedEntry {
23+
vec: self,
24+
pos: pos,
25+
}),
26+
None => Entry::Vacant(VacantEntry {
27+
vec: self,
28+
key: key,
29+
})
30+
}
31+
}
32+
33+
pub fn get(&self, key: &K) -> Option<&V> {
34+
self.find(key).map(move |pos| &self.vec[pos].1)
35+
}
36+
37+
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
38+
self.find(key).map(move |pos| &mut self.vec[pos].1)
39+
}
40+
41+
pub fn contains_key(&self, key: &K) -> bool {
42+
self.find(key).is_some()
43+
}
44+
45+
pub fn len(&self) -> usize { self.vec.len() }
46+
pub fn iter(&self) -> ::std::slice::Iter<(K, V)> {
47+
self.vec.iter()
48+
}
49+
pub fn remove(&mut self, key: &K) -> Option<V> {
50+
self.find(key).map(|pos| self.vec.remove(pos)).map(|(_, v)| v)
51+
}
52+
pub fn clear(&mut self) {
53+
self.vec.clear();
54+
}
55+
56+
fn find(&self, key: &K) -> Option<usize> {
57+
self.vec.iter().position(|entry| key == &entry.0)
58+
}
59+
}
60+
61+
pub enum Entry<'a, K: 'a, V: 'a> {
62+
Vacant(VacantEntry<'a, K, V>),
63+
Occupied(OccupiedEntry<'a, K, V>)
64+
}
65+
66+
pub struct VacantEntry<'a, K: 'a, V: 'a> {
67+
vec: &'a mut VecMap<K, V>,
68+
key: K,
69+
}
70+
71+
impl<'a, K, V> VacantEntry<'a, K, V> {
72+
pub fn insert(self, val: V) -> &'a mut V {
73+
let mut vec = self.vec;
74+
vec.vec.push((self.key, val));
75+
let pos = vec.vec.len() - 1;
76+
&mut vec.vec[pos].1
77+
}
78+
}
79+
80+
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
81+
vec: &'a mut VecMap<K, V>,
82+
pos: usize,
83+
}
84+
85+
impl<'a, K, V> OccupiedEntry<'a, K, V> {
86+
pub fn into_mut(self) -> &'a mut V {
87+
&mut self.vec.vec[self.pos].1
88+
}
89+
}

0 commit comments

Comments
 (0)