Skip to main content

reflexo_vfs/
trace.rs

1use std::{path::Path, sync::atomic::AtomicU64};
2
3use reflexo::ImmutPath;
4use typst::diag::FileResult;
5
6use crate::{AccessModel, Bytes};
7
8/// Provides trace access model which traces the underlying access model.
9///
10/// It simply wraps the underlying access model and prints all the access to the
11/// stdout or the browser console.
12#[derive(Debug)]
13pub struct TraceAccessModel<M: AccessModel + Sized> {
14    pub inner: M,
15    trace: [AtomicU64; 6],
16}
17
18impl<M: AccessModel + Sized> TraceAccessModel<M> {
19    /// Create a new [`TraceAccessModel`] with the given inner access model
20    pub fn new(inner: M) -> Self {
21        Self {
22            inner,
23            trace: Default::default(),
24        }
25    }
26}
27
28impl<M: AccessModel + Sized> AccessModel for TraceAccessModel<M> {
29    fn clear(&mut self) {
30        self.inner.clear();
31    }
32
33    fn mtime(&self, src: &Path) -> FileResult<crate::Time> {
34        let instant = reflexo::time::Instant::now();
35        let res = self.inner.mtime(src);
36        let elapsed = instant.elapsed();
37        // self.trace[0] += elapsed.as_nanos() as u64;
38        self.trace[0].fetch_add(
39            elapsed.as_nanos() as u64,
40            std::sync::atomic::Ordering::Relaxed,
41        );
42        crate::utils::console_log!("mtime: {:?} {:?} => {:?}", src, elapsed, res);
43        res
44    }
45
46    fn is_file(&self, src: &Path) -> FileResult<bool> {
47        let instant = reflexo::time::Instant::now();
48        let res = self.inner.is_file(src);
49        let elapsed = instant.elapsed();
50        self.trace[1].fetch_add(
51            elapsed.as_nanos() as u64,
52            std::sync::atomic::Ordering::Relaxed,
53        );
54        crate::utils::console_log!("is_file: {:?} {:?}", src, elapsed);
55        res
56    }
57
58    fn real_path(&self, src: &Path) -> FileResult<ImmutPath> {
59        let instant = reflexo::time::Instant::now();
60        let res = self.inner.real_path(src);
61        let elapsed = instant.elapsed();
62        self.trace[2].fetch_add(
63            elapsed.as_nanos() as u64,
64            std::sync::atomic::Ordering::Relaxed,
65        );
66        crate::utils::console_log!("real_path: {:?} {:?}", src, elapsed);
67        res
68    }
69
70    fn content(&self, src: &Path) -> FileResult<Bytes> {
71        let instant = reflexo::time::Instant::now();
72        let res = self.inner.content(src);
73        let elapsed = instant.elapsed();
74        self.trace[3].fetch_add(
75            elapsed.as_nanos() as u64,
76            std::sync::atomic::Ordering::Relaxed,
77        );
78        crate::utils::console_log!("read_all: {:?} {:?}", src, elapsed);
79        res
80    }
81}