Merge pull request #289 from hyperium/opt-cell
refactor(headers): switch from MuCell to OptCell
This commit is contained in:
@@ -15,7 +15,6 @@ keywords = ["http", "hyper", "hyperium"]
|
|||||||
cookie = "*"
|
cookie = "*"
|
||||||
log = ">= 0.2.0"
|
log = ">= 0.2.0"
|
||||||
mime = "*"
|
mime = "*"
|
||||||
mucell = "*"
|
|
||||||
openssl = "*"
|
openssl = "*"
|
||||||
rustc-serialize = "*"
|
rustc-serialize = "*"
|
||||||
time = "*"
|
time = "*"
|
||||||
|
|||||||
41
src/header/cell.rs
Normal file
41
src/header/cell.rs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
use std::cell::UnsafeCell;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
pub struct OptCell<T>(UnsafeCell<Option<T>>);
|
||||||
|
|
||||||
|
impl<T> OptCell<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(val: Option<T>) -> OptCell<T> {
|
||||||
|
OptCell(UnsafeCell::new(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set(&self, val: T) {
|
||||||
|
unsafe {
|
||||||
|
let opt = self.0.get();
|
||||||
|
debug_assert!((*opt).is_none());
|
||||||
|
*opt = Some(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn get_mut(&mut self) -> &mut T {
|
||||||
|
let opt = &mut *self.0.get();
|
||||||
|
opt.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Deref for OptCell<T> {
|
||||||
|
type Target = Option<T>;
|
||||||
|
#[inline]
|
||||||
|
fn deref<'a>(&'a self) -> &'a Option<T> {
|
||||||
|
unsafe { &*self.0.get() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Clone for OptCell<T> {
|
||||||
|
#[inline]
|
||||||
|
fn clone(&self) -> OptCell<T> {
|
||||||
|
OptCell::new((**self).clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,15 +16,16 @@ use std::iter::FromIterator;
|
|||||||
use std::borrow::IntoCow;
|
use std::borrow::IntoCow;
|
||||||
use std::{mem, raw};
|
use std::{mem, raw};
|
||||||
|
|
||||||
use mucell::MuCell;
|
|
||||||
use uany::{UnsafeAnyExt};
|
use uany::{UnsafeAnyExt};
|
||||||
use unicase::UniCase;
|
use unicase::UniCase;
|
||||||
|
|
||||||
|
use self::cell::OptCell;
|
||||||
use {http, HttpResult, HttpError};
|
use {http, HttpResult, HttpError};
|
||||||
|
|
||||||
pub use self::shared::{Encoding, QualityItem, qitem};
|
pub use self::shared::{Encoding, QualityItem, qitem};
|
||||||
pub use self::common::*;
|
pub use self::common::*;
|
||||||
|
|
||||||
|
mod cell;
|
||||||
mod common;
|
mod common;
|
||||||
mod shared;
|
mod shared;
|
||||||
pub mod parsing;
|
pub mod parsing;
|
||||||
@@ -115,7 +116,7 @@ fn header_name<T: Header>() -> &'static str {
|
|||||||
/// A map of header fields on requests and responses.
|
/// A map of header fields on requests and responses.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Headers {
|
pub struct Headers {
|
||||||
data: HashMap<HeaderName, MuCell<Item>>
|
data: HashMap<HeaderName, Item>
|
||||||
}
|
}
|
||||||
|
|
||||||
// To prevent DOS from a server sending a never ending header.
|
// To prevent DOS from a server sending a never ending header.
|
||||||
@@ -146,15 +147,10 @@ impl Headers {
|
|||||||
}
|
}
|
||||||
let name = UniCase(Owned(name));
|
let name = UniCase(Owned(name));
|
||||||
let mut item = match headers.data.entry(name) {
|
let mut item = match headers.data.entry(name) {
|
||||||
Entry::Vacant(entry) => entry.insert(MuCell::new(Item::raw(vec![]))),
|
Entry::Vacant(entry) => entry.insert(Item::new_raw(vec![])),
|
||||||
Entry::Occupied(entry) => entry.into_mut()
|
Entry::Occupied(entry) => entry.into_mut()
|
||||||
};
|
};
|
||||||
|
item.mut_raw().push(value);
|
||||||
match &mut item.borrow_mut().raw {
|
|
||||||
&mut Some(ref mut raw) => raw.push(value),
|
|
||||||
// Unreachable
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
None => break,
|
None => break,
|
||||||
}
|
}
|
||||||
@@ -167,7 +163,7 @@ impl Headers {
|
|||||||
/// The field is determined by the type of the value being set.
|
/// The field is determined by the type of the value being set.
|
||||||
pub fn set<H: Header + HeaderFormat>(&mut self, value: H) {
|
pub fn set<H: Header + HeaderFormat>(&mut self, value: H) {
|
||||||
self.data.insert(UniCase(Borrowed(header_name::<H>())),
|
self.data.insert(UniCase(Borrowed(header_name::<H>())),
|
||||||
MuCell::new(Item::typed(Box::new(value))));
|
Item::new_typed(Box::new(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access the raw value of a header.
|
/// Access the raw value of a header.
|
||||||
@@ -186,19 +182,15 @@ impl Headers {
|
|||||||
// FIXME(reem): Find a better way to do this lookup without find_equiv.
|
// FIXME(reem): Find a better way to do this lookup without find_equiv.
|
||||||
.get(&UniCase(Borrowed(unsafe { mem::transmute::<&str, &str>(name) })))
|
.get(&UniCase(Borrowed(unsafe { mem::transmute::<&str, &str>(name) })))
|
||||||
.and_then(|item| {
|
.and_then(|item| {
|
||||||
if let Some(ref raw) = item.borrow().raw {
|
if let Some(ref raw) = *item.raw {
|
||||||
return unsafe { mem::transmute(Some(&raw[])) };
|
return Some(&raw[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let worked = item.try_mutate(|item| {
|
let raw = vec![item.typed.as_ref().unwrap().to_string().into_bytes()];
|
||||||
let raw = vec![item.typed.as_ref().unwrap().to_string().into_bytes()];
|
item.raw.set(raw);
|
||||||
item.raw = Some(raw);
|
|
||||||
});
|
|
||||||
debug_assert!(worked, "item.try_mutate should return true");
|
|
||||||
|
|
||||||
let item = item.borrow();
|
|
||||||
let raw = item.raw.as_ref().unwrap();
|
let raw = item.raw.as_ref().unwrap();
|
||||||
unsafe { mem::transmute(Some(&raw[])) }
|
Some(&raw[])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,14 +204,14 @@ impl Headers {
|
|||||||
/// headers.set_raw("content-length", vec![b"5".to_vec()]);
|
/// headers.set_raw("content-length", vec![b"5".to_vec()]);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set_raw<K: IntoCow<'static, String, str>>(&mut self, name: K, value: Vec<Vec<u8>>) {
|
pub fn set_raw<K: IntoCow<'static, String, str>>(&mut self, name: K, value: Vec<Vec<u8>>) {
|
||||||
self.data.insert(UniCase(name.into_cow()), MuCell::new(Item::raw(value)));
|
self.data.insert(UniCase(name.into_cow()), Item::new_raw(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference to the header field's value, if it exists.
|
/// Get a reference to the header field's value, if it exists.
|
||||||
pub fn get<H: Header + HeaderFormat>(&self) -> Option<&H> {
|
pub fn get<H: Header + HeaderFormat>(&self) -> Option<&H> {
|
||||||
self.get_or_parse::<H>().map(|item| {
|
self.get_or_parse::<H>().map(|item| {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute::<&H, &H>(downcast(&*item.borrow()))
|
downcast(&*item)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -227,15 +219,15 @@ impl Headers {
|
|||||||
/// Get a mutable reference to the header field's value, if it exists.
|
/// Get a mutable reference to the header field's value, if it exists.
|
||||||
pub fn get_mut<H: Header + HeaderFormat>(&mut self) -> Option<&mut H> {
|
pub fn get_mut<H: Header + HeaderFormat>(&mut self) -> Option<&mut H> {
|
||||||
self.get_or_parse_mut::<H>().map(|item| {
|
self.get_or_parse_mut::<H>().map(|item| {
|
||||||
unsafe { downcast_mut(item.borrow_mut()) }
|
unsafe { downcast_mut(item) }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_parse<H: Header + HeaderFormat>(&self) -> Option<&MuCell<Item>> {
|
fn get_or_parse<H: Header + HeaderFormat>(&self) -> Option<&Item> {
|
||||||
self.data.get(&UniCase(Borrowed(header_name::<H>()))).and_then(get_or_parse::<H>)
|
self.data.get(&UniCase(Borrowed(header_name::<H>()))).and_then(get_or_parse::<H>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_parse_mut<H: Header + HeaderFormat>(&mut self) -> Option<&mut MuCell<Item>> {
|
fn get_or_parse_mut<H: Header + HeaderFormat>(&mut self) -> Option<&mut Item> {
|
||||||
self.data.get_mut(&UniCase(Borrowed(header_name::<H>()))).and_then(get_or_parse_mut::<H>)
|
self.data.get_mut(&UniCase(Borrowed(header_name::<H>()))).and_then(get_or_parse_mut::<H>)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,7 +291,7 @@ impl fmt::Debug for Headers {
|
|||||||
|
|
||||||
/// An `Iterator` over the fields in a `Headers` map.
|
/// An `Iterator` over the fields in a `Headers` map.
|
||||||
pub struct HeadersItems<'a> {
|
pub struct HeadersItems<'a> {
|
||||||
inner: Iter<'a, HeaderName, MuCell<Item>>
|
inner: Iter<'a, HeaderName, Item>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for HeadersItems<'a> {
|
impl<'a> Iterator for HeadersItems<'a> {
|
||||||
@@ -314,7 +306,7 @@ impl<'a> Iterator for HeadersItems<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returned with the `HeadersItems` iterator.
|
/// Returned with the `HeadersItems` iterator.
|
||||||
pub struct HeaderView<'a>(&'a HeaderName, &'a MuCell<Item>);
|
pub struct HeaderView<'a>(&'a HeaderName, &'a Item);
|
||||||
|
|
||||||
impl<'a> HeaderView<'a> {
|
impl<'a> HeaderView<'a> {
|
||||||
/// Check if a HeaderView is a certain Header.
|
/// Check if a HeaderView is a certain Header.
|
||||||
@@ -334,7 +326,7 @@ impl<'a> HeaderView<'a> {
|
|||||||
pub fn value<H: Header + HeaderFormat>(&self) -> Option<&'a H> {
|
pub fn value<H: Header + HeaderFormat>(&self) -> Option<&'a H> {
|
||||||
get_or_parse::<H>(self.1).map(|item| {
|
get_or_parse::<H>(self.1).map(|item| {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute::<&H, &H>(downcast(&*item.borrow()))
|
downcast(&*item)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -342,13 +334,13 @@ impl<'a> HeaderView<'a> {
|
|||||||
/// Get just the header value as a String.
|
/// Get just the header value as a String.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn value_string(&self) -> String {
|
pub fn value_string(&self) -> String {
|
||||||
(*self.1.borrow()).to_string()
|
(*self.1).to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Display for HeaderView<'a> {
|
impl<'a> fmt::Display for HeaderView<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}: {}", self.0, *self.1.borrow())
|
write!(f, "{}: {}", self.0, *self.1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,29 +368,47 @@ impl<'a> FromIterator<HeaderView<'a>> for Headers {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Item {
|
struct Item {
|
||||||
raw: Option<Vec<Vec<u8>>>,
|
raw: OptCell<Vec<Vec<u8>>>,
|
||||||
typed: Option<Box<HeaderFormat + Send + Sync>>
|
typed: OptCell<Box<HeaderFormat + Send + Sync>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
impl Item {
|
||||||
fn raw(data: Vec<Vec<u8>>) -> Item {
|
#[inline]
|
||||||
|
fn new_raw(data: Vec<Vec<u8>>) -> Item {
|
||||||
Item {
|
Item {
|
||||||
raw: Some(data),
|
raw: OptCell::new(Some(data)),
|
||||||
typed: None,
|
typed: OptCell::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn typed(ty: Box<HeaderFormat + Send + Sync>) -> Item {
|
#[inline]
|
||||||
|
fn new_typed(ty: Box<HeaderFormat + Send + Sync>) -> Item {
|
||||||
Item {
|
Item {
|
||||||
raw: None,
|
raw: OptCell::new(None),
|
||||||
typed: Some(ty),
|
typed: OptCell::new(Some(ty)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mut_raw(&mut self) -> &mut Vec<Vec<u8>> {
|
||||||
|
self.typed = OptCell::new(None);
|
||||||
|
unsafe {
|
||||||
|
self.raw.get_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mut_typed(&mut self) -> &mut Box<HeaderFormat + Send + Sync> {
|
||||||
|
self.raw = OptCell::new(None);
|
||||||
|
unsafe {
|
||||||
|
self.typed.get_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_parse<H: Header + HeaderFormat>(item: &MuCell<Item>) -> Option<&MuCell<Item>> {
|
|
||||||
match item.borrow().typed {
|
fn get_or_parse<H: Header + HeaderFormat>(item: &Item) -> Option<&Item> {
|
||||||
|
match *item.typed {
|
||||||
Some(ref typed) if typed.is::<H>() => return Some(item),
|
Some(ref typed) if typed.is::<H>() => return Some(item),
|
||||||
Some(ref typed) => {
|
Some(ref typed) => {
|
||||||
warn!("attempted to access {:?} as wrong type", typed);
|
warn!("attempted to access {:?} as wrong type", typed);
|
||||||
@@ -407,17 +417,16 @@ fn get_or_parse<H: Header + HeaderFormat>(item: &MuCell<Item>) -> Option<&MuCell
|
|||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
let worked = item.try_mutate(parse::<H>);
|
parse::<H>(item);
|
||||||
debug_assert!(worked, "item.try_mutate should return true");
|
if item.typed.is_some() {
|
||||||
if item.borrow().typed.is_some() {
|
|
||||||
Some(item)
|
Some(item)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_parse_mut<H: Header + HeaderFormat>(item: &mut MuCell<Item>) -> Option<&mut MuCell<Item>> {
|
fn get_or_parse_mut<H: Header + HeaderFormat>(item: &mut Item) -> Option<&mut Item> {
|
||||||
let is_correct_type = match item.borrow().typed {
|
let is_correct_type = match *item.typed {
|
||||||
Some(ref typed) if typed.is::<H>() => Some(true),
|
Some(ref typed) if typed.is::<H>() => Some(true),
|
||||||
Some(ref typed) => {
|
Some(ref typed) => {
|
||||||
warn!("attempted to access {:?} as wrong type", typed);
|
warn!("attempted to access {:?} as wrong type", typed);
|
||||||
@@ -432,37 +441,39 @@ fn get_or_parse_mut<H: Header + HeaderFormat>(item: &mut MuCell<Item>) -> Option
|
|||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
parse::<H>(item.borrow_mut());
|
parse::<H>(&item);
|
||||||
if item.borrow().typed.is_some() {
|
if item.typed.is_some() {
|
||||||
Some(item)
|
Some(item)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse<H: Header + HeaderFormat>(item: &mut Item) {
|
fn parse<H: Header + HeaderFormat>(item: &Item) {
|
||||||
item.typed = match item.raw {
|
match *item.raw {
|
||||||
Some(ref raw) => match Header::parse_header(&raw[]) {
|
Some(ref raw) => match Header::parse_header(&raw[]) {
|
||||||
Some::<H>(h) => Some(box h as Box<HeaderFormat + Send + Sync>),
|
Some::<H>(h) => item.typed.set(box h as Box<HeaderFormat + Send + Sync>),
|
||||||
None => None
|
None => ()
|
||||||
},
|
},
|
||||||
None => unreachable!()
|
None => unreachable!()
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn downcast<H: Header + HeaderFormat>(item: &Item) -> &H {
|
unsafe fn downcast<H: Header + HeaderFormat>(item: &Item) -> &H {
|
||||||
item.typed.as_ref().expect("item.typed must be set").downcast_ref_unchecked()
|
item.typed.as_ref().expect("item.typed must be set").downcast_ref_unchecked()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn downcast_mut<H: Header + HeaderFormat>(item: &mut Item) -> &mut H {
|
unsafe fn downcast_mut<H: Header + HeaderFormat>(item: &mut Item) -> &mut H {
|
||||||
item.typed.as_mut().expect("item.typed must be set").downcast_mut_unchecked()
|
item.mut_typed().downcast_mut_unchecked()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Item {
|
impl fmt::Display for Item {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self.typed {
|
match *self.typed {
|
||||||
Some(ref h) => h.fmt_header(fmt),
|
Some(ref h) => h.fmt_header(fmt),
|
||||||
None => match self.raw {
|
None => match *self.raw {
|
||||||
Some(ref raw) => {
|
Some(ref raw) => {
|
||||||
for part in raw.iter() {
|
for part in raw.iter() {
|
||||||
match from_utf8(&part[]) {
|
match from_utf8(&part[]) {
|
||||||
@@ -483,12 +494,14 @@ impl fmt::Display for Item {
|
|||||||
|
|
||||||
|
|
||||||
impl fmt::Debug for Box<HeaderFormat + Send + Sync> {
|
impl fmt::Debug for Box<HeaderFormat + Send + Sync> {
|
||||||
|
#[inline]
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
(**self).fmt_header(fmt)
|
(**self).fmt_header(fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Box<HeaderFormat + Send + Sync> {
|
impl fmt::Display for Box<HeaderFormat + Send + Sync> {
|
||||||
|
#[inline]
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
(**self).fmt_header(fmt)
|
(**self).fmt_header(fmt)
|
||||||
}
|
}
|
||||||
@@ -502,12 +515,14 @@ impl fmt::Display for Box<HeaderFormat + Send + Sync> {
|
|||||||
pub struct HeaderFormatter<'a, H: HeaderFormat>(pub &'a H);
|
pub struct HeaderFormatter<'a, H: HeaderFormat>(pub &'a H);
|
||||||
|
|
||||||
impl<'a, H: HeaderFormat> fmt::Display for HeaderFormatter<'a, H> {
|
impl<'a, H: HeaderFormat> fmt::Display for HeaderFormatter<'a, H> {
|
||||||
|
#[inline]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
self.0.fmt_header(f)
|
self.0.fmt_header(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, H: HeaderFormat> fmt::Debug for HeaderFormatter<'a, H> {
|
impl<'a, H: HeaderFormat> fmt::Debug for HeaderFormatter<'a, H> {
|
||||||
|
#[inline]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
self.0.fmt_header(f)
|
self.0.fmt_header(f)
|
||||||
}
|
}
|
||||||
@@ -695,37 +710,58 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_header_get(b: &mut Bencher) {
|
fn bench_headers_new(b: &mut Bencher) {
|
||||||
|
b.iter(|| {
|
||||||
|
let mut h = Headers::new();
|
||||||
|
h.set(ContentLength(11));
|
||||||
|
h
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_headers_from_raw(b: &mut Bencher) {
|
||||||
|
b.iter(|| Headers::from_raw(&mut mem("Content-Length: 10\r\n\r\n")).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_headers_get(b: &mut Bencher) {
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
headers.set(ContentLength(11));
|
headers.set(ContentLength(11));
|
||||||
b.iter(|| assert_eq!(headers.get::<ContentLength>(), Some(&ContentLength(11))))
|
b.iter(|| assert_eq!(headers.get::<ContentLength>(), Some(&ContentLength(11))))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_header_get_miss(b: &mut Bencher) {
|
fn bench_headers_get_miss(b: &mut Bencher) {
|
||||||
let headers = Headers::new();
|
let headers = Headers::new();
|
||||||
b.iter(|| assert!(headers.get::<ContentLength>().is_none()))
|
b.iter(|| assert!(headers.get::<ContentLength>().is_none()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_header_set(b: &mut Bencher) {
|
fn bench_headers_set(b: &mut Bencher) {
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
b.iter(|| headers.set(ContentLength(12)))
|
b.iter(|| headers.set(ContentLength(12)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_header_has(b: &mut Bencher) {
|
fn bench_headers_has(b: &mut Bencher) {
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
headers.set(ContentLength(11));
|
headers.set(ContentLength(11));
|
||||||
b.iter(|| assert!(headers.has::<ContentLength>()))
|
b.iter(|| assert!(headers.has::<ContentLength>()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn bench_header_view_is(b: &mut Bencher) {
|
fn bench_headers_view_is(b: &mut Bencher) {
|
||||||
let mut headers = Headers::new();
|
let mut headers = Headers::new();
|
||||||
headers.set(ContentLength(11));
|
headers.set(ContentLength(11));
|
||||||
let mut iter = headers.iter();
|
let mut iter = headers.iter();
|
||||||
let view = iter.next().unwrap();
|
let view = iter.next().unwrap();
|
||||||
b.iter(|| assert!(view.is::<ContentLength>()))
|
b.iter(|| assert!(view.is::<ContentLength>()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_headers_fmt(b: &mut Bencher) {
|
||||||
|
let mut headers = Headers::new();
|
||||||
|
headers.set(ContentLength(11));
|
||||||
|
b.iter(|| headers.to_string())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,6 @@ extern crate openssl;
|
|||||||
#[cfg(test)] extern crate test;
|
#[cfg(test)] extern crate test;
|
||||||
extern crate "unsafe-any" as uany;
|
extern crate "unsafe-any" as uany;
|
||||||
extern crate cookie;
|
extern crate cookie;
|
||||||
extern crate mucell;
|
|
||||||
extern crate unicase;
|
extern crate unicase;
|
||||||
|
|
||||||
pub use std::old_io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port};
|
pub use std::old_io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr, Port};
|
||||||
|
|||||||
Reference in New Issue
Block a user