Skip to main content

pagers_core/ops/
mod.rs

1mod evict;
2mod lock;
3mod lockall;
4mod process;
5mod query;
6mod touch;
7
8use std::fs::File;
9use std::path::Path;
10use std::sync::Arc;
11use std::sync::atomic::AtomicUsize;
12
13use memmap2::Mmap;
14
15use crate::mincore::{DefaultPageMap, PageMap};
16
17pub use evict::Evict;
18pub use lock::{Lock, LockedFile};
19pub use lockall::Lockall;
20pub(crate) use process::prepare_file;
21pub use process::{CountsResult, FileProcessed, FullResult, SkipResult, file_info};
22pub use query::Query;
23pub use touch::Touch;
24
25pub trait Op: Sync {
26    const LABEL: &str;
27    const MUTATES_RESIDENCY: bool = true;
28    /// Skip all residency checks; the after-state is known to be empty.
29    const SKIP_RESIDENCY: bool = false;
30    /// +1 for ops that add pages to cache (touch/lock), -1 for evict, 0 for query.
31    const ACTION_SIGN: isize = 0;
32
33    type Output: Send;
34    fn execute<PM: PageMap + Sync>(&self, ctx: &FileContext<'_, PM>)
35    -> crate::Result<Self::Output>;
36
37    fn finish(&self) -> crate::Result<()> {
38        Ok(())
39    }
40
41    fn action_pages(
42        _output: &Self::Output,
43        _total_pages: usize,
44        _pages_in_core_before: Option<usize>,
45        _pages_in_core_after: usize,
46    ) -> usize {
47        0
48    }
49}
50
51pub struct FileContext<'a, PM: PageMap = DefaultPageMap> {
52    pub file: &'a File,
53    pub path: &'a Path,
54    pub mmap: Arc<Mmap>,
55    pub offset: u64,
56    pub len: usize,
57    pub on_progress: Option<&'a (dyn Fn(usize, usize) + Sync)>,
58    pub residency: Option<&'a PM>,
59}
60
61impl<PM: PageMap> std::fmt::Debug for FileContext<'_, PM> {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        f.debug_struct("FileContext")
64            .field("path", &self.path)
65            .field("offset", &self.offset)
66            .field("len", &self.len)
67            .finish()
68    }
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq)]
72#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
73pub struct FileRange {
74    pub offset: u64,
75    pub max_len: Option<u64>,
76}
77
78#[derive(Debug, Clone, PartialEq)]
79#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
80pub struct FileInfo<PM = DefaultPageMap> {
81    pub total_pages: usize,
82    pub residency: PM,
83}
84
85#[derive(Debug)]
86pub struct Stats {
87    pub total_pages: AtomicUsize,
88    pub initial_pages_in_core: AtomicUsize,
89    pub action_pages: AtomicUsize,
90    pub total_files: AtomicUsize,
91    pub total_dirs: AtomicUsize,
92}
93
94impl Default for Stats {
95    fn default() -> Self {
96        Self::new()
97    }
98}
99
100impl Stats {
101    pub fn new() -> Self {
102        Self {
103            total_pages: AtomicUsize::new(0),
104            initial_pages_in_core: AtomicUsize::new(0),
105            action_pages: AtomicUsize::new(0),
106            total_files: AtomicUsize::new(0),
107            total_dirs: AtomicUsize::new(0),
108        }
109    }
110}