ipfs_sqlite_block_store/cache/
async_tracker.rs

1use super::{BlockInfo, CacheTracker, WriteInfo};
2use parking_lot::Mutex;
3use std::{fmt::Debug, sync::Arc};
4
5/// Wrapper around a spawn function
6pub trait Spawner: Send + Sync {
7    /// Called by the cache tracker to spawn a small, blocking, io bound task
8    fn spawn_blocking(&self, f: impl FnOnce() + Send + 'static);
9}
10
11/// A wrapping cache tracker that performs write operations on another thread
12pub struct AsyncCacheTracker<S, T> {
13    spawner: S,
14    inner: Arc<Mutex<T>>,
15}
16
17impl<S, T> Debug for AsyncCacheTracker<S, T> {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        f.debug_struct("AsyncCacheTracker").finish()
20    }
21}
22
23impl<S: Spawner, T: CacheTracker> AsyncCacheTracker<S, T> {
24    pub fn new(spawner: S, inner: T) -> Self {
25        Self {
26            spawner,
27            inner: Arc::new(Mutex::new(inner)),
28        }
29    }
30}
31
32impl<S, T> CacheTracker for AsyncCacheTracker<S, T>
33where
34    S: Spawner,
35    T: CacheTracker + 'static,
36{
37    fn blocks_accessed(&self, blocks: Vec<BlockInfo>) {
38        let inner = self.inner.clone();
39        self.spawner.spawn_blocking(move || {
40            inner.lock().blocks_accessed(blocks);
41        });
42    }
43
44    fn blocks_written(&self, blocks: Vec<WriteInfo>) {
45        let inner = self.inner.clone();
46        self.spawner.spawn_blocking(move || {
47            inner.lock().blocks_written(blocks);
48        });
49    }
50
51    fn blocks_deleted(&self, blocks: Vec<BlockInfo>) {
52        self.inner.lock().blocks_deleted(blocks);
53    }
54
55    fn retain_ids(&self, ids: &[i64]) {
56        self.inner.lock().retain_ids(ids);
57    }
58
59    fn sort_ids(&self, ids: &mut [i64]) {
60        self.inner.lock().sort_ids(ids);
61    }
62
63    fn has_persistent_state(&self) -> bool {
64        self.inner.lock().has_persistent_state()
65    }
66}