mirror of
https://github.com/fafhrd91/actix-web
synced 2025-07-01 16:55:08 +02:00
use custom headers map; more optimizations
This commit is contained in:
@ -5,7 +5,8 @@ use std::rc::Rc;
|
||||
use bitflags::bitflags;
|
||||
|
||||
use crate::extensions::Extensions;
|
||||
use crate::http::{header, HeaderMap, Method, StatusCode, Uri, Version};
|
||||
use crate::header::HeaderMap;
|
||||
use crate::http::{header, Method, StatusCode, Uri, Version};
|
||||
|
||||
/// Represents various types of connection
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
@ -174,7 +175,7 @@ impl Default for ResponseHead {
|
||||
ResponseHead {
|
||||
version: Version::default(),
|
||||
status: StatusCode::OK,
|
||||
headers: HeaderMap::with_capacity(16),
|
||||
headers: HeaderMap::with_capacity(12),
|
||||
reason: None,
|
||||
flags: Flags::empty(),
|
||||
extensions: RefCell::new(Extensions::new()),
|
||||
@ -182,18 +183,6 @@ impl Default for ResponseHead {
|
||||
}
|
||||
}
|
||||
|
||||
impl Head for ResponseHead {
|
||||
fn clear(&mut self) {
|
||||
self.reason = None;
|
||||
self.flags = Flags::empty();
|
||||
self.headers.clear();
|
||||
}
|
||||
|
||||
fn pool() -> &'static MessagePool<Self> {
|
||||
RESPONSE_POOL.with(|p| *p)
|
||||
}
|
||||
}
|
||||
|
||||
impl ResponseHead {
|
||||
/// Message extensions
|
||||
#[inline]
|
||||
@ -300,7 +289,6 @@ impl ResponseHead {
|
||||
|
||||
pub struct Message<T: Head> {
|
||||
head: Rc<T>,
|
||||
pool: &'static MessagePool<T>,
|
||||
}
|
||||
|
||||
impl<T: Head> Message<T> {
|
||||
@ -314,7 +302,6 @@ impl<T: Head> Clone for Message<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Message {
|
||||
head: self.head.clone(),
|
||||
pool: self.pool,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -336,17 +323,52 @@ impl<T: Head> std::ops::DerefMut for Message<T> {
|
||||
impl<T: Head> Drop for Message<T> {
|
||||
fn drop(&mut self) {
|
||||
if Rc::strong_count(&self.head) == 1 {
|
||||
self.pool.release(self.head.clone());
|
||||
T::pool().release(self.head.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct BoxedResponseHead {
|
||||
head: Option<Box<ResponseHead>>,
|
||||
}
|
||||
|
||||
impl BoxedResponseHead {
|
||||
/// Get new message from the pool of objects
|
||||
pub fn new() -> Self {
|
||||
RESPONSE_POOL.with(|p| p.get_message())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for BoxedResponseHead {
|
||||
type Target = ResponseHead;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.head.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for BoxedResponseHead {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.head.as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for BoxedResponseHead {
|
||||
fn drop(&mut self) {
|
||||
RESPONSE_POOL.with(|p| p.release(self.head.take().unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Request's objects pool
|
||||
pub struct MessagePool<T: Head>(RefCell<VecDeque<Rc<T>>>);
|
||||
|
||||
#[doc(hidden)]
|
||||
/// Request's objects pool
|
||||
pub struct BoxedResponsePool(RefCell<VecDeque<Box<ResponseHead>>>);
|
||||
|
||||
thread_local!(static REQUEST_POOL: &'static MessagePool<RequestHead> = MessagePool::<RequestHead>::create());
|
||||
thread_local!(static RESPONSE_POOL: &'static MessagePool<ResponseHead> = MessagePool::<ResponseHead>::create());
|
||||
thread_local!(static RESPONSE_POOL: &'static BoxedResponsePool = BoxedResponsePool::create());
|
||||
|
||||
impl<T: Head> MessagePool<T> {
|
||||
fn create() -> &'static MessagePool<T> {
|
||||
@ -361,14 +383,10 @@ impl<T: Head> MessagePool<T> {
|
||||
if let Some(r) = Rc::get_mut(&mut msg) {
|
||||
r.clear();
|
||||
}
|
||||
Message {
|
||||
head: msg,
|
||||
pool: self,
|
||||
}
|
||||
Message { head: msg }
|
||||
} else {
|
||||
Message {
|
||||
head: Rc::new(T::default()),
|
||||
pool: self,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -382,3 +400,34 @@ impl<T: Head> MessagePool<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BoxedResponsePool {
|
||||
fn create() -> &'static BoxedResponsePool {
|
||||
let pool = BoxedResponsePool(RefCell::new(VecDeque::with_capacity(128)));
|
||||
Box::leak(Box::new(pool))
|
||||
}
|
||||
|
||||
/// Get message from the pool
|
||||
#[inline]
|
||||
fn get_message(&'static self) -> BoxedResponseHead {
|
||||
if let Some(mut head) = self.0.borrow_mut().pop_front() {
|
||||
head.reason = None;
|
||||
head.headers.clear();
|
||||
head.flags = Flags::empty();
|
||||
BoxedResponseHead { head: Some(head) }
|
||||
} else {
|
||||
BoxedResponseHead {
|
||||
head: Some(Box::new(ResponseHead::default())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Release request instance
|
||||
fn release(&self, msg: Box<ResponseHead>) {
|
||||
let v = &mut self.0.borrow_mut();
|
||||
if v.len() < 128 {
|
||||
v.push_front(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user