Skip to main content

Mountain/Cache/AssetMemoryMap/
LoadOrInsert.rs

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