pre-warm content cache
in parallel!
This commit is contained in:
parent
42eaa326ab
commit
5193fc2be0
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1951,6 +1951,7 @@ dependencies = [
|
|||
"jotdown",
|
||||
"log",
|
||||
"rand",
|
||||
"rayon",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
|
@ -25,6 +25,7 @@ indexmap = { version = "2.2.6", features = ["serde"] }
|
|||
jotdown = { version = "0.4.1", default-features = false }
|
||||
log = { workspace = true }
|
||||
rand = "0.8.5"
|
||||
rayon = "1.10.0"
|
||||
regex = "1.10.3"
|
||||
serde = { version = "1.0.183", features = ["derive"] }
|
||||
serde_json = "1.0.105"
|
||||
|
|
|
@ -514,7 +514,9 @@ pub fn target(dirs: Arc<Dirs>, sources: Arc<Sources>) -> DynDir {
|
|||
|
||||
let dir_index = DirIndex::new(sources.parsed_trees.keys().map(|x| &**x));
|
||||
let tree_view = TreehouseDir::new(dirs, sources, dir_index);
|
||||
|
||||
let tree_view = ContentCache::new(tree_view);
|
||||
tree_view.warm_up();
|
||||
let tree_view = HtmlCanonicalize::new(tree_view);
|
||||
|
||||
Overlay::new(tree_view.to_dyn(), root.to_dyn()).to_dyn()
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
use std::fmt::{self, Debug};
|
||||
use std::{
|
||||
fmt::{self, Debug},
|
||||
ops::ControlFlow,
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
use log::debug;
|
||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||
|
||||
use super::{Dir, DirEntry, EditPath, ImageSize, VPath, VPathBuf};
|
||||
use super::{walk_dir_rec, Dir, DirEntry, EditPath, ImageSize, VPath, VPathBuf};
|
||||
|
||||
pub struct ContentCache<T> {
|
||||
inner: T,
|
||||
|
@ -18,6 +23,22 @@ impl<T> ContentCache<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> ContentCache<T>
|
||||
where
|
||||
T: Dir + Send + Sync,
|
||||
{
|
||||
pub fn warm_up(&self) {
|
||||
debug!("warm_up({self:?})");
|
||||
let mut paths = vec![];
|
||||
walk_dir_rec(&self.inner, VPath::ROOT, &mut |path| {
|
||||
paths.push(path.to_owned());
|
||||
ControlFlow::Continue(())
|
||||
});
|
||||
|
||||
paths.par_iter().for_each(|path| _ = self.content(path));
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Dir for ContentCache<T>
|
||||
where
|
||||
T: Dir,
|
||||
|
|
|
@ -91,10 +91,16 @@ impl VPath {
|
|||
}
|
||||
|
||||
pub fn segments(&self) -> impl Iterator<Item = &Self> {
|
||||
self.as_str().split(Self::SEPARATOR).map(|s| unsafe {
|
||||
// SAFETY: Since we're splitting on the separator, the path cannot start or end with it.
|
||||
Self::new_unchecked(s)
|
||||
})
|
||||
if self.is_root() {
|
||||
None.into_iter().flatten()
|
||||
} else {
|
||||
Some(self.as_str().split(Self::SEPARATOR).map(|s| unsafe {
|
||||
// SAFETY: Since we're splitting on the separator, the path cannot start or end with it.
|
||||
Self::new_unchecked(s)
|
||||
}))
|
||||
.into_iter()
|
||||
.flatten()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rsegments(&self) -> impl Iterator<Item = &Self> {
|
||||
|
@ -203,7 +209,9 @@ impl VPathBuf {
|
|||
|
||||
pub fn push(&mut self, sub: &VPath) {
|
||||
if !sub.is_empty() {
|
||||
self.path.push('/');
|
||||
if !self.is_empty() {
|
||||
self.path.push('/');
|
||||
}
|
||||
self.path.push_str(&sub.path);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue