sled/context.rs
1use super::*;
2
3#[derive(Debug, Clone)]
4#[doc(hidden)]
5pub struct Context {
6 // TODO file from config should be in here
7 config: RunningConfig,
8 /// Periodically flushes dirty data. We keep this in an
9 /// Arc separate from the PageCache below to separate
10 /// "high-level" references from Db, Tree etc... from
11 /// "low-level" references like background threads.
12 /// When the last high-level reference is dropped, it
13 /// should trigger all background threads to clean
14 /// up synchronously.
15 #[cfg(all(
16 not(miri),
17 any(
18 windows,
19 target_os = "linux",
20 target_os = "macos",
21 target_os = "dragonfly",
22 target_os = "freebsd",
23 target_os = "openbsd",
24 target_os = "netbsd",
25 )
26 ))]
27 pub(crate) flusher: Arc<Mutex<Option<flusher::Flusher>>>,
28 #[doc(hidden)]
29 pub pagecache: Arc<PageCache>,
30}
31
32impl std::ops::Deref for Context {
33 type Target = RunningConfig;
34
35 fn deref(&self) -> &RunningConfig {
36 &self.config
37 }
38}
39
40impl Context {
41 pub(crate) fn start(config: RunningConfig) -> Result<Self> {
42 trace!("starting context");
43
44 let pagecache = Arc::new(PageCache::start(config.clone())?);
45
46 Ok(Self {
47 config,
48 pagecache,
49 #[cfg(all(
50 not(miri),
51 any(
52 windows,
53 target_os = "linux",
54 target_os = "macos",
55 target_os = "dragonfly",
56 target_os = "freebsd",
57 target_os = "openbsd",
58 target_os = "netbsd",
59 )
60 ))]
61 flusher: Arc::new(parking_lot::Mutex::new(None)),
62 })
63 }
64
65 /// Returns `true` if the database was
66 /// recovered from a previous process.
67 /// Note that database state is only
68 /// guaranteed to be present up to the
69 /// last call to `flush`! Otherwise state
70 /// is synced to disk periodically if the
71 /// `sync_every_ms` configuration option
72 /// is set to `Some(number_of_ms_between_syncs)`
73 /// or if the IO buffer gets filled to
74 /// capacity before being rotated.
75 pub fn was_recovered(&self) -> bool {
76 self.pagecache.was_recovered()
77 }
78
79 /// Generate a monotonic ID. Not guaranteed to be
80 /// contiguous. Written to disk every `idgen_persist_interval`
81 /// operations, followed by a blocking flush. During recovery, we
82 /// take the last recovered generated ID and add 2x
83 /// the `idgen_persist_interval` to it. While persisting, if the
84 /// previous persisted counter wasn't synced to disk yet, we will do
85 /// a blocking flush to fsync the latest counter, ensuring
86 /// that we will never give out the same counter twice.
87 pub fn generate_id(&self) -> Result<u64> {
88 let _cc = concurrency_control::read();
89 self.pagecache.generate_id_inner()
90 }
91
92 pub(crate) fn pin_log(&self, guard: &Guard) -> Result<RecoveryGuard<'_>> {
93 self.pagecache.pin_log(guard)
94 }
95}