iroh_bytes/
store.rs

1//! Implementations of blob stores
2use crate::{BlobFormat, Hash, HashAndFormat};
3
4#[cfg(feature = "fs-store")]
5mod bao_file;
6pub mod mem;
7mod mutable_mem_storage;
8pub mod readonly_mem;
9
10#[cfg(feature = "fs-store")]
11pub mod fs;
12
13mod traits;
14pub use traits::*;
15
16/// Create a 16 byte unique ID.
17fn new_uuid() -> [u8; 16] {
18    use rand::Rng;
19    rand::thread_rng().gen::<[u8; 16]>()
20}
21
22/// Create temp file name based on a 16 byte UUID.
23fn temp_name() -> String {
24    format!("{}.temp", hex::encode(new_uuid()))
25}
26
27#[derive(Debug, Default, Clone)]
28struct TempCounters {
29    /// number of raw temp tags for a hash
30    raw: u64,
31    /// number of hash seq temp tags for a hash
32    hash_seq: u64,
33}
34
35impl TempCounters {
36    fn counter(&mut self, format: BlobFormat) -> &mut u64 {
37        match format {
38            BlobFormat::Raw => &mut self.raw,
39            BlobFormat::HashSeq => &mut self.hash_seq,
40        }
41    }
42
43    fn inc(&mut self, format: BlobFormat) {
44        let counter = self.counter(format);
45        *counter = counter.checked_add(1).unwrap();
46    }
47
48    fn dec(&mut self, format: BlobFormat) {
49        let counter = self.counter(format);
50        *counter = counter.saturating_sub(1);
51    }
52
53    fn is_empty(&self) -> bool {
54        self.raw == 0 && self.hash_seq == 0
55    }
56}
57
58#[derive(Debug, Clone, Default)]
59struct TempCounterMap(std::collections::BTreeMap<Hash, TempCounters>);
60
61impl TempCounterMap {
62    fn inc(&mut self, value: &HashAndFormat) {
63        let HashAndFormat { hash, format } = value;
64        self.0.entry(*hash).or_default().inc(*format)
65    }
66
67    fn dec(&mut self, value: &HashAndFormat) {
68        let HashAndFormat { hash, format } = value;
69        let counters = self.0.get_mut(hash).unwrap();
70        counters.dec(*format);
71        if counters.is_empty() {
72            self.0.remove(hash);
73        }
74    }
75
76    fn contains(&self, hash: &Hash) -> bool {
77        self.0.contains_key(hash)
78    }
79
80    fn keys(&self) -> impl Iterator<Item = HashAndFormat> {
81        let mut res = Vec::new();
82        for (k, v) in self.0.iter() {
83            if v.raw > 0 {
84                res.push(HashAndFormat::raw(*k));
85            }
86            if v.hash_seq > 0 {
87                res.push(HashAndFormat::hash_seq(*k));
88            }
89        }
90        res.into_iter()
91    }
92}