Skip to main content

Cache/AssetMemoryMap/
LoadOrInsert.rs

1//! Load `Path` into the cache (or return the existing entry).
2//!
3//! Returns `Err` only if the file cannot be opened or memory-mapped;
4//! missing brotli siblings are silently ignored (best-effort
5//! optimisation).
6
7use std::{
8	path::{Path, PathBuf},
9	sync::Arc,
10};
11
12use memmap2::Mmap;
13
14use crate::AssetMemoryMap::{Entry, Map, MimeFromExtension};
15
16pub fn Fn(Path:&Path) -> std::io::Result<Arc<Entry::Struct>> {
17	if let Some(Existing) = Map::Fn().get(Path) {
18		return Ok(Existing.clone());
19	}
20
21	let File = std::fs::File::open(Path)?;
22
23	let Length = File.metadata()?.len() as usize;
24
25	// SAFETY: caller agrees the file is not truncated underneath us
26	// for the lifetime of the MemoryMap. The bundle directory is
27	// read-only at runtime; mutations happen at build time and require
28	// a binary restart.
29	let Mapping = unsafe { Mmap::map(&File)? };
30
31	let BrotliPath = {
32		let mut B = Path.as_os_str().to_owned();
33
34		B.push(".br");
35
36		PathBuf::from(B)
37	};
38
39	let Brotli = std::fs::File::open(&BrotliPath)
40		.ok()
41		.and_then(|F| unsafe { Mmap::map(&F).ok() });
42
43	let Mime = MimeFromExtension::Fn(Path);
44
45	let MarkerEntry = Arc::new(Entry::Struct { Mapping, Mime, Length, Brotli });
46
47	log::debug!(
48		target:"asset-cache",
49
50		"mmap insert path={} bytes={} brotli={}",
51
52		Path.display(),
53
54		Length,
55
56		MarkerEntry.Brotli.is_some()
57	);
58
59	Map::Fn().insert(Path.to_path_buf(), MarkerEntry.clone());
60
61	Ok(MarkerEntry)
62}