driven/binary/
memory_map.rs1use crate::{DrivenError, Result};
6use memmap2::Mmap;
7use std::fs::File;
8use std::path::Path;
9
10#[derive(Debug)]
12pub struct MappedRule {
13 mmap: Mmap,
15 path: std::path::PathBuf,
17}
18
19impl MappedRule {
20 pub fn open(path: &Path) -> Result<Self> {
22 let file = File::open(path).map_err(|e| {
23 DrivenError::Io(std::io::Error::new(
24 e.kind(),
25 format!("Failed to open {}: {}", path.display(), e),
26 ))
27 })?;
28
29 let mmap = unsafe { Mmap::map(&file) }.map_err(|e| {
31 DrivenError::Io(std::io::Error::other(format!(
32 "Failed to mmap {}: {}",
33 path.display(),
34 e
35 )))
36 })?;
37
38 Ok(Self {
39 mmap,
40 path: path.to_path_buf(),
41 })
42 }
43
44 pub fn as_bytes(&self) -> &[u8] {
46 &self.mmap
47 }
48
49 pub fn len(&self) -> usize {
51 self.mmap.len()
52 }
53
54 pub fn is_empty(&self) -> bool {
56 self.mmap.is_empty()
57 }
58
59 pub fn path(&self) -> &Path {
61 &self.path
62 }
63
64 pub fn advise_sequential(&self) -> Result<()> {
66 #[cfg(unix)]
67 {
68 self.mmap.advise(memmap2::Advice::Sequential).map_err(|e| {
69 DrivenError::Io(std::io::Error::new(
70 std::io::ErrorKind::Other,
71 e.to_string(),
72 ))
73 })?;
74 }
75 Ok(())
76 }
77
78 pub fn advise_willneed(&self) -> Result<()> {
80 #[cfg(unix)]
81 {
82 self.mmap.advise(memmap2::Advice::WillNeed).map_err(|e| {
83 DrivenError::Io(std::io::Error::new(
84 std::io::ErrorKind::Other,
85 e.to_string(),
86 ))
87 })?;
88 }
89 Ok(())
90 }
91}
92
93#[derive(Debug, Default)]
95pub struct RuleMapping;
96
97impl RuleMapping {
98 pub fn can_map(path: &Path) -> bool {
100 path.is_file() && path.metadata().map(|m| m.len() > 0).unwrap_or(false)
101 }
102
103 pub fn strategy(size: u64) -> MappingStrategy {
105 if size < 4096 {
106 MappingStrategy::ReadAll } else if size < 1024 * 1024 {
108 MappingStrategy::MapPrivate } else {
110 MappingStrategy::MapShared }
112 }
113}
114
115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
117pub enum MappingStrategy {
118 ReadAll,
120 MapPrivate,
122 MapShared,
124}
125
126#[derive(Debug)]
128pub struct PreloadedRule {
129 data: Vec<u8>,
131 path: std::path::PathBuf,
133}
134
135impl PreloadedRule {
136 pub fn load(path: &Path) -> Result<Self> {
138 let data = std::fs::read(path)?;
139 Ok(Self {
140 data,
141 path: path.to_path_buf(),
142 })
143 }
144
145 pub fn as_bytes(&self) -> &[u8] {
147 &self.data
148 }
149
150 pub fn len(&self) -> usize {
152 self.data.len()
153 }
154
155 pub fn is_empty(&self) -> bool {
157 self.data.is_empty()
158 }
159
160 pub fn path(&self) -> &Path {
162 &self.path
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169
170 #[test]
171 fn test_mapping_strategy() {
172 assert_eq!(RuleMapping::strategy(100), MappingStrategy::ReadAll);
173 assert_eq!(RuleMapping::strategy(10_000), MappingStrategy::MapPrivate);
174 assert_eq!(
175 RuleMapping::strategy(10_000_000),
176 MappingStrategy::MapShared
177 );
178 }
179}