1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//! Line Cache
//!
//! An LRU-cache for lines.
use std::borrow::Cow;
use lru::LruCache;
use regex::bytes::Regex;
use crate::file::{File, FileInfo};
use crate::line::Line;
/// An LRU-cache for Lines.
pub(crate) struct LineCache(LruCache<usize, Line>);
impl LineCache {
/// Create a new LineCache with the given capacity.
pub(crate) fn new(capacity: usize) -> LineCache {
LineCache(LruCache::new(capacity))
}
/// Get a line out of the line cache, or create it if it is not
/// in the cache.
pub(crate) fn get_or_create<'a>(
&'a mut self,
file: &File,
line_index: usize,
regex: Option<&Regex>,
) -> Option<Cow<'a, Line>> {
let cache = &mut self.0;
if cache.contains(&line_index) {
Some(Cow::Borrowed(cache.get_mut(&line_index).unwrap()))
} else {
let line = file.with_line(line_index, |line| {
if let Some(ref regex) = regex {
Line::new_search(line_index, line, regex)
} else {
Line::new(line_index, line)
}
});
if let Some(line) = line {
// Don't cache the line if it's the last line of the file
// and the file is still loading. It might not be complete.
if file.loaded() || line_index + 1 < file.lines() {
cache.put(line_index, line);
Some(Cow::Borrowed(cache.get_mut(&line_index).unwrap()))
} else {
Some(Cow::Owned(line))
}
} else {
None
}
}
}
/// Clear all entries in the line cache.
pub(crate) fn clear(&mut self) {
self.0.clear();
}
}