Skip to main content

pagers_core/ops/
evict.rs

1use crate::mincore::PageMap;
2
3use super::{FileContext, Op};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub struct Evict;
8
9impl Op for Evict {
10    const LABEL: &str = "evicted";
11    const SKIP_RESIDENCY: bool = true;
12    const ACTION_SIGN: isize = -1;
13    type Output = ();
14
15    fn action_pages(
16        _output: &(),
17        total_pages: usize,
18        pages_in_core_before: Option<usize>,
19        pages_in_core_after: usize,
20    ) -> usize {
21        let before = pages_in_core_before.unwrap_or(total_pages);
22        before.saturating_sub(pages_in_core_after)
23    }
24
25    fn execute<PM: PageMap + Sync>(&self, ctx: &FileContext<'_, PM>) -> crate::Result<()> {
26        tracing::debug!("Evicting {}", ctx.path.display());
27
28        #[cfg(target_os = "linux")]
29        {
30            use std::os::unix::io::AsFd;
31            nix::fcntl::posix_fadvise(
32                ctx.file.as_fd(),
33                ctx.offset as libc::off_t,
34                ctx.len as libc::off_t,
35                nix::fcntl::PosixFadviseAdvice::POSIX_FADV_DONTNEED,
36            )?;
37        }
38
39        #[cfg(target_os = "macos")]
40        {
41            use nix::sys::mman::{MsFlags, msync};
42            use std::ptr::NonNull;
43
44            unsafe {
45                let ptr = NonNull::new(ctx.mmap.as_ptr() as *mut _)
46                    .expect("mmap pointer should be non-null");
47                msync(ptr, ctx.len, MsFlags::MS_INVALIDATE)?;
48            }
49        }
50
51        Ok(())
52    }
53}