1use std::{path::Path, sync::atomic::AtomicU64};
2
3use reflexo::ImmutPath;
4use typst::diag::FileResult;
5
6use crate::{AccessModel, Bytes};
7
8#[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 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].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}