in below/store/src/cursor.rs [175:222]
fn get_mmap(&self, file_type: StoreFile, shard: u64) -> Result<Option<Mmap>> {
let prefix = match file_type {
StoreFile::Index => "index",
StoreFile::Data => "data",
};
let path = self.path.join(format!("{}_{:011}", prefix, shard));
let file = match File::open(&path) {
Ok(f) => f,
Err(e) if e.kind() == ErrorKind::NotFound => {
warn!(
self.logger,
"Expected file does not exist: {}",
path.display()
);
return Ok(None);
}
Err(e) => {
return Err(e).context(format!("Failed while opening file: {}", path.display()));
}
};
let mut len = file
.metadata()
.with_context(|| format!("Failed to get metadata of file: {}", path.display()))?
.len() as usize;
if let StoreFile::Index = file_type {
len = len - len % INDEX_ENTRY_SIZE;
}
if len == 0 {
warn!(self.logger, "0 length file found: {}", path.display());
return Ok(None);
}
// Mmap is unsafe because it allows unrestricted concurrent access. In
// our case, we only have one background process (below record) doing
// append-only writes to both index and data files. We also use CRC to
// verify file content. As long as we do read-only operations here, this
// should be Ok.
unsafe {
Some(
MmapOptions::new()
.len(len)
.map(&file)
.with_context(|| format!("Failed to mmap file {}", path.display())),
)
.transpose()
}
}