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}