gix_odb/store_impls/dynamic/
metrics.rs

1use std::sync::atomic::Ordering;
2
3use crate::store::{types, types::IndexAndPacks};
4
5impl super::Store {
6    /// Return metrics collected in a racy fashion, giving an idea of what's currently going on in the store.
7    ///
8    /// Use this to decide whether a new instance should be created to get a chance at dropping all open handles.
9    pub fn metrics(&self) -> types::Metrics {
10        let mut open_packs = 0;
11        let mut open_indices = 0;
12        let mut known_packs = 0;
13        let mut known_indices = 0;
14        let mut unused_slots = 0;
15        let mut unreachable_indices = 0;
16        let mut unreachable_packs = 0;
17
18        let index = self.index.load();
19        for f in index.slot_indices.iter().map(|idx| &self.files[*idx]) {
20            match &**f.files.load() {
21                Some(IndexAndPacks::Index(bundle)) => {
22                    if bundle.index.is_loaded() {
23                        open_indices += 1;
24                    }
25                    known_indices += 1;
26                    if bundle.data.is_loaded() {
27                        open_packs += 1;
28                    }
29                    known_packs += 1;
30                }
31                Some(IndexAndPacks::MultiIndex(multi)) => {
32                    if multi.multi_index.is_loaded() {
33                        open_indices += 1;
34                    }
35                    known_indices += 1;
36                    for pack in &multi.data {
37                        if pack.is_loaded() {
38                            open_packs += 1;
39                        }
40                        known_packs += 1;
41                    }
42                }
43                None => {}
44            }
45        }
46
47        for slot in &self.files {
48            match slot.files.load().as_ref() {
49                None => {
50                    unused_slots += 1;
51                }
52                Some(bundle) => {
53                    if bundle.is_disposable() {
54                        unreachable_indices += 1;
55                        unreachable_packs += match bundle {
56                            IndexAndPacks::Index(single) => usize::from(single.data.is_loaded()),
57                            IndexAndPacks::MultiIndex(multi) => {
58                                multi.data.iter().map(|p| usize::from(p.is_loaded())).sum()
59                            }
60                        }
61                    }
62                }
63            }
64        }
65
66        types::Metrics {
67            num_handles: self.num_handles_unstable.load(Ordering::Relaxed)
68                + self.num_handles_stable.load(Ordering::Relaxed),
69            num_refreshes: self.num_disk_state_consolidation.load(Ordering::Relaxed),
70            open_reachable_packs: open_packs,
71            open_reachable_indices: open_indices,
72            known_reachable_indices: known_indices,
73            known_packs,
74            unused_slots,
75            loose_dbs: index.loose_dbs.len(),
76            unreachable_indices,
77            unreachable_packs,
78        }
79    }
80}