linecache/
lib.rs

1use dashmap::DashMap;
2use std::fs;
3use std::io;
4use std::sync::Arc;
5use tokio::fs::File;
6use tokio::io::AsyncBufReadExt;
7use rand::seq::SliceRandom; // 导入 SliceRandom trait
8use std::time::SystemTime;
9
10pub struct AsyncLineCache {
11    pub cache: Arc<DashMap<String, String>>, // 缓存文件行内容
12    pub file_times: Arc<DashMap<String, SystemTime>>, // 缓存文件的最后修改时间
13    pub file_lines: Arc<DashMap<String, Vec<String>>>, // 缓存文件的所有行
14}
15
16impl AsyncLineCache {
17    pub fn new() -> Self {
18        let cache = Arc::new(DashMap::new()); // 使用 DashMap 缓存文件行内容
19        let file_times = Arc::new(DashMap::new()); // 使用 DashMap 缓存文件的最后修改时间
20        let file_lines = Arc::new(DashMap::new()); // 使用 DashMap 缓存文件的所有行
21        AsyncLineCache { cache, file_times, file_lines }
22    }
23
24    pub async fn get_line(&self, filename: &str, lineno: usize) -> io::Result<Option<String>> {
25        println!("正在从文件 {} 中获取第 {} 行...", filename, lineno);
26        let file_metadata = fs::metadata(filename)?;
27        let last_modified = file_metadata.modified()?;
28        // 检查文件是否更新
29        let cached_time = self.file_times.get(filename).map(|entry| *entry.value());
30        if cached_time.is_none() || cached_time.unwrap() < last_modified {
31            println!("文件已更新,正在重新加载缓存...");
32            self.check_cache(filename).await?;
33        }
34        println!("缓存检查完成...");
35        // 生成缓存键:文件名 + 行号
36        let key = format!("{}:{}", filename, lineno);
37        if let Some(line) = self.cache.get(&key) {
38            println!("从缓存中找到行内容: {:?}", line);
39            return Ok(Some(line.value().clone()));
40        }
41        // 如果缓存中没有,从文件中读取
42        if let Some(lines) = self.file_lines.get(filename) {
43            if lineno <= lines.len() {
44                let line = lines[lineno - 1].clone();
45                self.cache.insert(key, line.clone());
46                println!("从文件中读取行内容: {}", line);
47                return Ok(Some(line));
48            }
49        }
50        println!("文件 {} 中未找到第 {} 行", filename, lineno);
51        Ok(None)
52    }
53
54    pub async fn get_lines(&self, filename: &str) -> io::Result<Option<Vec<String>>> {
55        println!("正在从文件 {} 中获取所有行...", filename);
56        let file_metadata = fs::metadata(filename)?;
57        let last_modified = file_metadata.modified()?;
58        // 检查文件是否更新
59        let cached_time = self.file_times.get(filename).map(|entry| *entry.value());
60        if cached_time.is_none() || cached_time.unwrap() < last_modified {
61            println!("文件已更新,正在重新加载缓存...");
62            self.check_cache(filename).await?;
63        }
64        println!("缓存检查完成...");
65        // 从缓存中获取所有行
66        if let Some(lines) = self.file_lines.get(filename) {
67            println!("成功获取文件 {} 的所有行", filename);
68            return Ok(Some(lines.value().clone()));
69        }
70        println!("文件 {} 未找到或为空", filename);
71        Ok(None)
72    }
73
74    pub async fn random_line(&self, filename: &str) -> io::Result<Option<String>> {
75        let file_metadata = fs::metadata(filename)?;
76        let last_modified = file_metadata.modified()?;
77        // 检查文件是否更新
78        let cached_time = self.file_times.get(filename).map(|entry| *entry.value());
79        if cached_time.is_none() || cached_time.unwrap() < last_modified {
80            self.check_cache(filename).await?;
81        }
82        // 从缓存中获取所有行并随机选择一行
83        if let Some(lines) = self.file_lines.get(filename) {
84            if !lines.is_empty() {
85                let random_line = lines.choose(&mut rand::thread_rng()).cloned();
86                return Ok(random_line);
87            }
88        }
89        Ok(None)
90    }
91
92    pub async fn clear_cache(&self) {
93        // 清空行内容缓存
94        self.cache.clear();
95        // 清空文件修改时间缓存
96        self.file_times.clear();
97        // 清空文件行缓存
98        self.file_lines.clear();
99    }
100
101    async fn check_cache(&self, filename: &str) -> io::Result<()> {
102        let file_metadata = fs::metadata(filename)?;
103        let last_modified = file_metadata.modified()?;
104        if let Some(cached_time) = self.file_times.get(filename).map(|entry| *entry.value()) {
105            if cached_time < last_modified {
106                println!("文件已更新,正在重新加载...");
107                self.reload_file(filename).await?;
108            }
109        } else {
110            println!("文件未缓存,正在加载...");
111            self.load_file(filename).await?;
112        }
113        Ok(())
114    }
115
116    async fn load_file(&self, filename: &str) -> io::Result<()> {
117        let file = File::open(filename).await?;
118        let reader = tokio::io::BufReader::new(file);
119        let mut lines = Vec::new();
120        let mut lines_stream = reader.lines();
121        // 逐行读取文件内容
122        while let Some(line) = lines_stream.next_line().await? {
123            lines.push(line);
124        }
125        self.file_lines.insert(filename.to_string(), lines);
126        let file_metadata = fs::metadata(filename)?;
127        let last_modified = file_metadata.modified()?;
128        self.file_times.insert(filename.to_string(), last_modified);
129        Ok(())
130    }
131
132    async fn reload_file(&self, filename: &str) -> io::Result<()> {
133        self.file_lines.remove(filename);
134        self.load_file(filename).await
135    }
136}