swh_graph/properties/
utils.rs

1// Copyright (C) 2023-2025  The Software Heritage developers
2// See the AUTHORS file at the top-level directory of this distribution
3// License: GNU General Public License version 3, or any later version
4// See top-level LICENSE file for more information
5
6use std::path::Path;
7
8use anyhow::{Context, Result};
9
10use super::*;
11use crate::utils::suffix_path;
12
13pub(super) fn load_if_exists<T>(
14    base_path: &Path,
15    suffix: &'static str,
16    f: impl FnOnce(&Path) -> Result<T>,
17) -> Result<Result<T, UnavailableProperty>> {
18    let path = suffix_path(base_path, suffix);
19    if std::fs::exists(&path).map_err(|source| UnavailableProperty {
20        path: path.clone(),
21        source,
22    })? {
23        Ok(Ok(f(&path)?))
24    } else {
25        Ok(Err(UnavailableProperty {
26            path,
27            source: std::io::Error::new(std::io::ErrorKind::NotFound, "No such file"),
28        }))
29    }
30}
31
32pub(super) fn mmap(path: impl AsRef<Path>) -> Result<Mmap> {
33    let path = path.as_ref();
34    let file_len = path
35        .metadata()
36        .with_context(|| format!("Could not stat {}", path.display()))?
37        .len();
38    let file =
39        std::fs::File::open(path).with_context(|| format!("Could not open {}", path.display()))?;
40    let data = unsafe {
41        mmap_rs::MmapOptions::new(file_len as _)
42            .with_context(|| format!("Could not initialize mmap of size {file_len}"))?
43            .with_flags(
44                mmap_rs::MmapFlags::TRANSPARENT_HUGE_PAGES | mmap_rs::MmapFlags::RANDOM_ACCESS,
45            )
46            .with_file(&file, 0)
47            .map()
48            .with_context(|| format!("Could not mmap {}", path.display()))?
49    };
50    Ok(data)
51}