Struct DeviceManager

Source
pub struct DeviceManager {
    pub reader: Reader,
    pub last_load_time: Option<Duration>,
    /* private fields */
}

Fields§

§reader: Reader§last_load_time: Option<Duration>

Implementations§

Source§

impl DeviceManager

Source

pub fn new(filename: &str) -> Result<Self, Error>

Source

pub fn new_with_cache_size( filename: &str, max_cache_size: usize, ) -> Result<Self, Error>

Source

pub fn match_device(&self, user_agent: &str) -> Device<'_>

Examples found in repository?
examples/simple_match.rs (line 30)
5fn main() -> Result<(), std::io::Error> {
6    let args: Vec<String> = env::args().collect();
7
8    let db_file = args
9        .get(1)
10        .map(|s| s.as_str())
11        .unwrap_or("/Users/zhaopeng/project/devcache/51Degrees-EnterpriseV3.4.trie");
12
13    let default_ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0";
14    let user_agent = args.get(2).map(|s| s.as_str()).unwrap_or(default_ua);
15
16    println!("开始加载设备数据库文件...");
17    let total_start = Instant::now();
18
19    // 创建DeviceManager实例
20    match create_device_manager(db_file) {
21        Ok(manager) => {
22            // 获取加载时间
23            if let Some(duration) = manager.get_load_time() {
24                println!("数据库加载完成,耗时: {:?}", duration);
25            }
26
27            // 首次解析(未缓存)
28            println!("\n首次解析User-Agent (未缓存)...");
29            let first_parse_start = Instant::now();
30            let device = manager.match_device(user_agent);
31            let first_parse_time = first_parse_start.elapsed();
32            println!("首次解析完成,耗时: {:?}", first_parse_time);
33
34            println!("\n基本匹配结果:");
35            print_device_info(&device);
36
37            // 再次解析相同的UA(使用缓存)
38            println!("\n再次解析相同User-Agent (使用缓存)...");
39            let second_parse_start = Instant::now();
40            let _device = manager.match_device(user_agent);
41            let second_parse_time = second_parse_start.elapsed();
42            println!("二次解析完成,耗时: {:?}", second_parse_time);
43
44            // 计算性能提升
45            if first_parse_time > second_parse_time {
46                let speedup =
47                    first_parse_time.as_nanos() as f64 / second_parse_time.as_nanos() as f64;
48                println!("\n缓存性能提升: {:.2}倍", speedup);
49            }
50
51            // 打印缓存统计
52            let (hits, misses, hit_rate) = manager.get_cache_stats();
53            println!("\n缓存统计:");
54            println!("  命中次数: {}", hits);
55            println!("  未命中次数: {}", misses);
56            println!("  命中率: {:.2}%", hit_rate);
57            println!("  当前缓存大小: {}", manager.get_cache_size());
58
59            // 批量测试
60            println!("\n执行10次相同查询的批量测试...");
61            let batch_start = Instant::now();
62
63            for i in 1..=10 {
64                let start = Instant::now();
65                let _device = manager.match_device(user_agent);
66                println!("  查询 #{}: {:?}", i, start.elapsed());
67            }
68
69            println!("10次查询总耗时: {:?}", batch_start.elapsed());
70
71            // 再次查看缓存统计
72            let (hits, misses, hit_rate) = manager.get_cache_stats();
73            println!("\n更新后的缓存统计:");
74            println!("  命中次数: {}", hits);
75            println!("  未命中次数: {}", misses);
76            println!("  命中率: {:.2}%", hit_rate);
77
78            // 总计耗时
79            println!("\n总计耗时: {:?}", total_start.elapsed());
80        }
81        Err(e) => println!("创建设备管理器出错: {}", e),
82    }
83
84    Ok(())
85}
Source

pub fn get_cached_property( &self, user_agent: &str, property_name: &str, ) -> Option<String>

Source

pub fn get_load_time(&self) -> Option<Duration>

Examples found in repository?
examples/simple_match.rs (line 23)
5fn main() -> Result<(), std::io::Error> {
6    let args: Vec<String> = env::args().collect();
7
8    let db_file = args
9        .get(1)
10        .map(|s| s.as_str())
11        .unwrap_or("/Users/zhaopeng/project/devcache/51Degrees-EnterpriseV3.4.trie");
12
13    let default_ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0";
14    let user_agent = args.get(2).map(|s| s.as_str()).unwrap_or(default_ua);
15
16    println!("开始加载设备数据库文件...");
17    let total_start = Instant::now();
18
19    // 创建DeviceManager实例
20    match create_device_manager(db_file) {
21        Ok(manager) => {
22            // 获取加载时间
23            if let Some(duration) = manager.get_load_time() {
24                println!("数据库加载完成,耗时: {:?}", duration);
25            }
26
27            // 首次解析(未缓存)
28            println!("\n首次解析User-Agent (未缓存)...");
29            let first_parse_start = Instant::now();
30            let device = manager.match_device(user_agent);
31            let first_parse_time = first_parse_start.elapsed();
32            println!("首次解析完成,耗时: {:?}", first_parse_time);
33
34            println!("\n基本匹配结果:");
35            print_device_info(&device);
36
37            // 再次解析相同的UA(使用缓存)
38            println!("\n再次解析相同User-Agent (使用缓存)...");
39            let second_parse_start = Instant::now();
40            let _device = manager.match_device(user_agent);
41            let second_parse_time = second_parse_start.elapsed();
42            println!("二次解析完成,耗时: {:?}", second_parse_time);
43
44            // 计算性能提升
45            if first_parse_time > second_parse_time {
46                let speedup =
47                    first_parse_time.as_nanos() as f64 / second_parse_time.as_nanos() as f64;
48                println!("\n缓存性能提升: {:.2}倍", speedup);
49            }
50
51            // 打印缓存统计
52            let (hits, misses, hit_rate) = manager.get_cache_stats();
53            println!("\n缓存统计:");
54            println!("  命中次数: {}", hits);
55            println!("  未命中次数: {}", misses);
56            println!("  命中率: {:.2}%", hit_rate);
57            println!("  当前缓存大小: {}", manager.get_cache_size());
58
59            // 批量测试
60            println!("\n执行10次相同查询的批量测试...");
61            let batch_start = Instant::now();
62
63            for i in 1..=10 {
64                let start = Instant::now();
65                let _device = manager.match_device(user_agent);
66                println!("  查询 #{}: {:?}", i, start.elapsed());
67            }
68
69            println!("10次查询总耗时: {:?}", batch_start.elapsed());
70
71            // 再次查看缓存统计
72            let (hits, misses, hit_rate) = manager.get_cache_stats();
73            println!("\n更新后的缓存统计:");
74            println!("  命中次数: {}", hits);
75            println!("  未命中次数: {}", misses);
76            println!("  命中率: {:.2}%", hit_rate);
77
78            // 总计耗时
79            println!("\n总计耗时: {:?}", total_start.elapsed());
80        }
81        Err(e) => println!("创建设备管理器出错: {}", e),
82    }
83
84    Ok(())
85}
Source

pub fn get_parse_time(&self) -> Option<Duration>

Source

pub fn get_cache_stats(&self) -> (usize, usize, f64)

Examples found in repository?
examples/simple_match.rs (line 52)
5fn main() -> Result<(), std::io::Error> {
6    let args: Vec<String> = env::args().collect();
7
8    let db_file = args
9        .get(1)
10        .map(|s| s.as_str())
11        .unwrap_or("/Users/zhaopeng/project/devcache/51Degrees-EnterpriseV3.4.trie");
12
13    let default_ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0";
14    let user_agent = args.get(2).map(|s| s.as_str()).unwrap_or(default_ua);
15
16    println!("开始加载设备数据库文件...");
17    let total_start = Instant::now();
18
19    // 创建DeviceManager实例
20    match create_device_manager(db_file) {
21        Ok(manager) => {
22            // 获取加载时间
23            if let Some(duration) = manager.get_load_time() {
24                println!("数据库加载完成,耗时: {:?}", duration);
25            }
26
27            // 首次解析(未缓存)
28            println!("\n首次解析User-Agent (未缓存)...");
29            let first_parse_start = Instant::now();
30            let device = manager.match_device(user_agent);
31            let first_parse_time = first_parse_start.elapsed();
32            println!("首次解析完成,耗时: {:?}", first_parse_time);
33
34            println!("\n基本匹配结果:");
35            print_device_info(&device);
36
37            // 再次解析相同的UA(使用缓存)
38            println!("\n再次解析相同User-Agent (使用缓存)...");
39            let second_parse_start = Instant::now();
40            let _device = manager.match_device(user_agent);
41            let second_parse_time = second_parse_start.elapsed();
42            println!("二次解析完成,耗时: {:?}", second_parse_time);
43
44            // 计算性能提升
45            if first_parse_time > second_parse_time {
46                let speedup =
47                    first_parse_time.as_nanos() as f64 / second_parse_time.as_nanos() as f64;
48                println!("\n缓存性能提升: {:.2}倍", speedup);
49            }
50
51            // 打印缓存统计
52            let (hits, misses, hit_rate) = manager.get_cache_stats();
53            println!("\n缓存统计:");
54            println!("  命中次数: {}", hits);
55            println!("  未命中次数: {}", misses);
56            println!("  命中率: {:.2}%", hit_rate);
57            println!("  当前缓存大小: {}", manager.get_cache_size());
58
59            // 批量测试
60            println!("\n执行10次相同查询的批量测试...");
61            let batch_start = Instant::now();
62
63            for i in 1..=10 {
64                let start = Instant::now();
65                let _device = manager.match_device(user_agent);
66                println!("  查询 #{}: {:?}", i, start.elapsed());
67            }
68
69            println!("10次查询总耗时: {:?}", batch_start.elapsed());
70
71            // 再次查看缓存统计
72            let (hits, misses, hit_rate) = manager.get_cache_stats();
73            println!("\n更新后的缓存统计:");
74            println!("  命中次数: {}", hits);
75            println!("  未命中次数: {}", misses);
76            println!("  命中率: {:.2}%", hit_rate);
77
78            // 总计耗时
79            println!("\n总计耗时: {:?}", total_start.elapsed());
80        }
81        Err(e) => println!("创建设备管理器出错: {}", e),
82    }
83
84    Ok(())
85}
Source

pub fn clear_cache(&self)

Source

pub fn get_cache_size(&self) -> usize

Examples found in repository?
examples/simple_match.rs (line 57)
5fn main() -> Result<(), std::io::Error> {
6    let args: Vec<String> = env::args().collect();
7
8    let db_file = args
9        .get(1)
10        .map(|s| s.as_str())
11        .unwrap_or("/Users/zhaopeng/project/devcache/51Degrees-EnterpriseV3.4.trie");
12
13    let default_ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0";
14    let user_agent = args.get(2).map(|s| s.as_str()).unwrap_or(default_ua);
15
16    println!("开始加载设备数据库文件...");
17    let total_start = Instant::now();
18
19    // 创建DeviceManager实例
20    match create_device_manager(db_file) {
21        Ok(manager) => {
22            // 获取加载时间
23            if let Some(duration) = manager.get_load_time() {
24                println!("数据库加载完成,耗时: {:?}", duration);
25            }
26
27            // 首次解析(未缓存)
28            println!("\n首次解析User-Agent (未缓存)...");
29            let first_parse_start = Instant::now();
30            let device = manager.match_device(user_agent);
31            let first_parse_time = first_parse_start.elapsed();
32            println!("首次解析完成,耗时: {:?}", first_parse_time);
33
34            println!("\n基本匹配结果:");
35            print_device_info(&device);
36
37            // 再次解析相同的UA(使用缓存)
38            println!("\n再次解析相同User-Agent (使用缓存)...");
39            let second_parse_start = Instant::now();
40            let _device = manager.match_device(user_agent);
41            let second_parse_time = second_parse_start.elapsed();
42            println!("二次解析完成,耗时: {:?}", second_parse_time);
43
44            // 计算性能提升
45            if first_parse_time > second_parse_time {
46                let speedup =
47                    first_parse_time.as_nanos() as f64 / second_parse_time.as_nanos() as f64;
48                println!("\n缓存性能提升: {:.2}倍", speedup);
49            }
50
51            // 打印缓存统计
52            let (hits, misses, hit_rate) = manager.get_cache_stats();
53            println!("\n缓存统计:");
54            println!("  命中次数: {}", hits);
55            println!("  未命中次数: {}", misses);
56            println!("  命中率: {:.2}%", hit_rate);
57            println!("  当前缓存大小: {}", manager.get_cache_size());
58
59            // 批量测试
60            println!("\n执行10次相同查询的批量测试...");
61            let batch_start = Instant::now();
62
63            for i in 1..=10 {
64                let start = Instant::now();
65                let _device = manager.match_device(user_agent);
66                println!("  查询 #{}: {:?}", i, start.elapsed());
67            }
68
69            println!("10次查询总耗时: {:?}", batch_start.elapsed());
70
71            // 再次查看缓存统计
72            let (hits, misses, hit_rate) = manager.get_cache_stats();
73            println!("\n更新后的缓存统计:");
74            println!("  命中次数: {}", hits);
75            println!("  未命中次数: {}", misses);
76            println!("  命中率: {:.2}%", hit_rate);
77
78            // 总计耗时
79            println!("\n总计耗时: {:?}", total_start.elapsed());
80        }
81        Err(e) => println!("创建设备管理器出错: {}", e),
82    }
83
84    Ok(())
85}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.