destiny_pkg/manager/
lookup_cache.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use itertools::MultiUnzip;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use tracing::{debug_span, error, info};

use super::{PackageManager, TagLookupIndex};
use crate::manager::HashTableEntryShort;

impl PackageManager {
    // const LOOKUP_CACHE_VERSION: u32 = 1;

    #[cfg(feature = "ignore_package_cache")]
    pub(super) fn read_lookup_cache(&self) -> Option<PathCache> {
        if !silent {
            info!("Not loading tag cache: ignore_package_cache is enabled")
        }
        None
    }

    #[cfg(feature = "ignore_package_cache")]
    pub(super) fn write_lookup_cache(&self) -> anyhow::Result<()> {
        Ok(())
    }

    #[cfg(not(feature = "ignore_package_cache"))]
    pub(super) fn read_lookup_cache(&self) -> Option<TagLookupIndex> {
        use std::io::Read;

        use crate::manager::path_cache::exe_relative_path;

        let mut file = std::fs::File::open(exe_relative_path(&format!(
            "lookup_cache_{}.bin",
            self.cache_key()
        )))
        .ok()?;

        let mut cache_data = Vec::new();
        file.read_to_end(&mut cache_data).ok()?;

        info!("Loading index cache");

        let cache: Option<TagLookupIndex> =
            bincode::decode_from_slice(&cache_data, bincode::config::standard())
                .map(|(v, _)| v)
                .ok();

        cache
    }

    #[cfg(not(feature = "ignore_package_cache"))]
    pub(super) fn write_lookup_cache(&self) -> anyhow::Result<()> {
        use super::path_cache::exe_relative_path;

        Ok(std::fs::write(
            exe_relative_path(&format!("lookup_cache_{}.bin", self.cache_key())),
            bincode::encode_to_vec(&self.lookup, bincode::config::standard())?,
        )?)
    }

    pub fn build_lookup_tables(&mut self) {
        let start = std::time::Instant::now();
        let tables: Vec<_> = self
            .package_paths
            .par_iter()
            .filter_map(|(_, p)| {
                let _span = debug_span!("Read package tables", package = p.path).entered();
                let pkg = match self.version.open(&p.path) {
                    Ok(package) => package,
                    Err(e) => {
                        error!("Failed to open package '{}': {e}", p.filename);
                        return None;
                    }
                };
                let entries = (pkg.pkg_id(), pkg.entries().to_vec());

                let collect = pkg
                    .hash64_table()
                    .iter()
                    .map(|h| {
                        (
                            h.hash64,
                            HashTableEntryShort {
                                hash32: h.hash32,
                                reference: h.reference,
                            },
                        )
                    })
                    .collect::<Vec<(u64, HashTableEntryShort)>>();
                let hashes = collect;

                let named_tags = pkg.named_tags();

                Some((entries, hashes, named_tags))
            })
            .collect();

        let (entries, hashes, named_tags): (_, Vec<_>, Vec<_>) = tables.into_iter().multiunzip();

        self.lookup = TagLookupIndex {
            tag32_entries_by_pkg: entries,
            tag64_entries: hashes.into_iter().flatten().collect(),
            named_tags: named_tags.into_iter().flatten().collect(),
        };

        info!(
            "Built lookup table for {} packages in {:?}",
            self.lookup.tag32_entries_by_pkg.len(),
            start.elapsed()
        );
    }
}