1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 09:42:40 +01:00

transmute names once

This commit is contained in:
Nikolay Kim 2018-06-22 11:44:38 +06:00
parent fc7238baee
commit 6c44575923

View File

@ -1,5 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::mem;
use std::rc::Rc; use std::rc::Rc;
use regex::{escape, Regex}; use regex::{escape, Regex};
@ -143,7 +144,7 @@ enum PatternElement {
enum PatternType { enum PatternType {
Static(String), Static(String),
Prefix(String), Prefix(String),
Dynamic(Regex, Vec<String>, usize), Dynamic(Regex, Vec<&'static str>, usize),
} }
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -216,9 +217,17 @@ impl Resource {
Ok(re) => re, Ok(re) => re,
Err(err) => panic!("Wrong path pattern: \"{}\" {}", path, err), Err(err) => panic!("Wrong path pattern: \"{}\" {}", path, err),
}; };
// actix creates one router per thread
let names = re let names = re
.capture_names() .capture_names()
.filter_map(|name| name.map(|name| name.to_owned())) .filter_map(|name| {
name.map(|name| {
let name = name.to_owned();
let s: &'static str = unsafe { mem::transmute(name.as_str()) };
mem::forget(name);
s
})
})
.collect(); .collect();
PatternType::Dynamic(re, names, len) PatternType::Dynamic(re, names, len)
} else if for_prefix { } else if for_prefix {
@ -308,10 +317,7 @@ impl Resource {
let params = req.match_info_mut(); let params = req.match_info_mut();
params.set_tail(len as u16); params.set_tail(len as u16);
for (idx, segment) in segments.iter().enumerate() { for (idx, segment) in segments.iter().enumerate() {
// reason: Router is part of App, which is unique per thread params.add(names[idx], *segment);
// app is alive during whole life of a thread
let name = unsafe { &*(names[idx].as_str() as *const _) };
params.add(name, *segment);
} }
true true
} }
@ -377,10 +383,7 @@ impl Resource {
let params = req.match_info_mut(); let params = req.match_info_mut();
params.set_tail(tail_len as u16); params.set_tail(tail_len as u16);
for (idx, segment) in segments.iter().enumerate() { for (idx, segment) in segments.iter().enumerate() {
// reason: Router is part of App, which is unique per thread params.add(names[idx], *segment);
// app is alive during whole life of a thread
let name = unsafe { &*(names[idx].as_str() as *const _) };
params.add(name, *segment);
} }
Some(tail_len) Some(tail_len)
} }