Skip to content

Commit 573c9ba

Browse files
authored
disk: initialize the LruDiskCache in a background thread (#868)
Co-Authored-by: @glandium
1 parent b8c26a1 commit 573c9ba

File tree

1 file changed

+42
-12
lines changed

1 file changed

+42
-12
lines changed

src/cache/disk.rs

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,64 @@
1515
use crate::cache::{Cache, CacheRead, CacheWrite, Storage};
1616
use crate::lru_disk_cache::Error as LruError;
1717
use crate::lru_disk_cache::LruDiskCache;
18-
use std::ffi::OsStr;
18+
use std::ffi::{OsStr, OsString};
1919
use std::path::{Path, PathBuf};
2020
use std::sync::{Arc, Mutex};
2121
use std::time::{Duration, Instant};
2222

2323
use crate::errors::*;
2424

25+
enum LazyDiskCache {
26+
Uninit { root: OsString, max_size: u64 },
27+
Init(LruDiskCache),
28+
}
29+
30+
impl LazyDiskCache {
31+
fn get_or_init(&mut self) -> Result<&mut LruDiskCache> {
32+
match self {
33+
LazyDiskCache::Uninit { root, max_size } => {
34+
*self = LazyDiskCache::Init(LruDiskCache::new(&root, *max_size)?);
35+
self.get_or_init()
36+
}
37+
LazyDiskCache::Init(d) => Ok(d),
38+
}
39+
}
40+
41+
fn get(&mut self) -> Option<&mut LruDiskCache> {
42+
match self {
43+
LazyDiskCache::Uninit { .. } => None,
44+
LazyDiskCache::Init(d) => Some(d),
45+
}
46+
}
47+
48+
fn path(&self) -> &Path {
49+
match self {
50+
LazyDiskCache::Uninit { root, .. } => root.as_ref(),
51+
LazyDiskCache::Init(d) => d.path(),
52+
}
53+
}
54+
}
55+
2556
/// A cache that stores entries at local disk paths.
26-
#[derive(Clone)]
2757
pub struct DiskCache {
2858
/// `LruDiskCache` does all the real work here.
29-
lru: Arc<Mutex<LruDiskCache>>,
59+
lru: Arc<Mutex<LazyDiskCache>>,
3060
/// Thread pool to execute disk I/O
3161
pool: tokio::runtime::Handle,
3262
}
3363

3464
impl DiskCache {
3565
/// Create a new `DiskCache` rooted at `root`, with `max_size` as the maximum cache size on-disk, in bytes.
3666
pub fn new<T: AsRef<OsStr>>(
37-
root: &T,
67+
root: T,
3868
max_size: u64,
3969
pool: &tokio::runtime::Handle,
4070
) -> DiskCache {
4171
DiskCache {
42-
//TODO: change this function to return a Result
43-
lru: Arc::new(Mutex::new(
44-
LruDiskCache::new(root, max_size).expect("Couldn't instantiate disk cache!"),
45-
)),
72+
lru: Arc::new(Mutex::new(LazyDiskCache::Uninit {
73+
root: root.as_ref().to_os_string(),
74+
max_size,
75+
})),
4676
pool: pool.clone(),
4777
}
4878
}
@@ -64,7 +94,7 @@ impl Storage for DiskCache {
6494
self.pool
6595
.spawn_blocking(move || {
6696
let mut lru = lru.lock().unwrap();
67-
let io = match lru.get(&path) {
97+
let io = match lru.get_or_init()?.get(&path) {
6898
Ok(f) => f,
6999
Err(LruError::FileNotInCache) => {
70100
trace!("DiskCache::get({}): FileNotInCache", key);
@@ -93,7 +123,7 @@ impl Storage for DiskCache {
93123
.spawn_blocking(move || {
94124
let start = Instant::now();
95125
let v = entry.finish()?;
96-
lru.lock().unwrap().insert_bytes(key, &v)?;
126+
lru.lock().unwrap().get_or_init()?.insert_bytes(key, &v)?;
97127
Ok(start.elapsed())
98128
})
99129
.await?
@@ -104,9 +134,9 @@ impl Storage for DiskCache {
104134
}
105135

106136
async fn current_size(&self) -> Result<Option<u64>> {
107-
Ok(Some(self.lru.lock().unwrap().size()))
137+
Ok(self.lru.lock().unwrap().get().map(|l| l.size()))
108138
}
109139
async fn max_size(&self) -> Result<Option<u64>> {
110-
Ok(Some(self.lru.lock().unwrap().capacity()))
140+
Ok(self.lru.lock().unwrap().get().map(|l| l.capacity()))
111141
}
112142
}

0 commit comments

Comments
 (0)