tawasuyu

tawasuyu/brahman

Rust 321TOML 122JSON 14Markdown 114332 Sutichaykuna

⎇ 53dbdf0f1deea10d6fc567ea2b43e1e75d6d60cd crates/modules/semantic_dht/minga-store/src/mst_store.rs Rust · 74 siq'ikuna · 2.2 KB Ñawpa willay Pi imata llamkarqan ch'uya

chore: monorepo inicial con arje + minga + yahweh absorbidos 53dbdf0f1 · Sergio ·

1//! Persistencia del MST.
2//!
3//! Solo persistimos las **claves** (los `ContentHash`es del conjunto).
4//! La estructura probabilística del MST (niveles, separadores,
5//! árbol de Merkle) es derivable determinísticamente de las claves,
6//! así que reconstruirla en memoria al cargar es trivial.
7//!
8//! Layout: una `sled::Tree` cuyas claves son los 32 bytes del hash y
9//! cuyos valores son vacíos. Los hashes se ordenan automáticamente
10//! por sled (orden lexicográfico = orden por bytes), lo que coincide
11//! con el orden que `Mst::iter` produce.
12
13use minga_core::{ContentHash, Mst};
14use sled::{Db, Tree};
15
16use crate::error::StoreError;
17
18pub struct SledMstStore {
19    tree: Tree,
20}
21
22impl SledMstStore {
23    pub fn open_tree(db: &Db, name: &str) -> Result<Self, StoreError> {
24        Ok(Self {
25            tree: db.open_tree(name)?,
26        })
27    }
28
29    pub fn insert(&self, h: ContentHash) -> Result<bool, StoreError> {
30        let prev = self.tree.insert(h.0, &[])?;
31        Ok(prev.is_none())
32    }
33
34    pub fn contains(&self, h: &ContentHash) -> Result<bool, StoreError> {
35        Ok(self.tree.contains_key(h.0)?)
36    }
37
38    pub fn len(&self) -> usize {
39        self.tree.len()
40    }
41
42    pub fn is_empty(&self) -> bool {
43        self.tree.is_empty()
44    }
45
46    /// Itera todas las claves del MST en orden ascendente por hash.
47    pub fn iter(&self) -> impl Iterator<Item = Result<ContentHash, StoreError>> + '_ {
48        self.tree.iter().map(|kv| {
49            let (k, _) = kv?;
50            if k.len() != 32 {
51                return Err(StoreError::HashMismatch);
52            }
53            let mut bytes = [0u8; 32];
54            bytes.copy_from_slice(&k);
55            Ok(ContentHash(bytes))
56        })
57    }
58
59    /// Reconstruye un `Mst` en memoria a partir de las claves
60    /// persistidas. Útil al arrancar un peer: cargamos las claves
61    /// del disco y rehacemos la estructura para operaciones rápidas.
62    pub fn to_in_memory(&self) -> Result<Mst, StoreError> {
63        let mut mst = Mst::new();
64        for h in self.iter() {
65            mst.insert(h?);
66        }
67        Ok(mst)
68    }
69
70    pub fn flush(&self) -> Result<(), StoreError> {
71        self.tree.flush()?;
72        Ok(())
73    }
74}