guardian_db/stores/kv_store/
index.rs

1use crate::error::GuardianError;
2use crate::ipfs_log::{entry::Entry, log::Log};
3use crate::stores::operation::operation::Operation;
4use crate::traits::StoreIndex;
5use parking_lot::RwLock;
6use std::collections::{HashMap, HashSet};
7use std::sync::Arc;
8/// KvIndex mantém um índice de chave-valor em memória para a KvStore.
9pub struct KvIndex {
10    index: Arc<RwLock<HashMap<String, Vec<u8>>>>,
11}
12
13impl Default for KvIndex {
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl KvIndex {
20    /// Cria uma nova instância de KvIndex.
21    pub fn new() -> Self {
22        KvIndex {
23            index: Arc::new(RwLock::new(HashMap::new())),
24        }
25    }
26}
27
28impl StoreIndex for KvIndex {
29    type Error = GuardianError;
30
31    /// Verifica se uma chave existe no índice.
32    fn contains_key(&self, key: &str) -> std::result::Result<bool, Self::Error> {
33        let index = self.index.read();
34        Ok(index.contains_key(key))
35    }
36
37    /// Retorna uma cópia dos dados para uma chave específica como bytes.
38    fn get_bytes(&self, key: &str) -> std::result::Result<Option<Vec<u8>>, Self::Error> {
39        let index = self.index.read();
40        Ok(index.get(key).cloned())
41    }
42
43    /// Retorna todas as chaves disponíveis no índice.
44    fn keys(&self) -> std::result::Result<Vec<String>, Self::Error> {
45        let index = self.index.read();
46        Ok(index.keys().cloned().collect())
47    }
48
49    /// Retorna o número de entradas no índice.
50    fn len(&self) -> std::result::Result<usize, Self::Error> {
51        let index = self.index.read();
52        Ok(index.len())
53    }
54
55    /// Verifica se o índice está vazio.
56    fn is_empty(&self) -> std::result::Result<bool, Self::Error> {
57        let index = self.index.read();
58        Ok(index.is_empty())
59    }
60    /// Atualiza o índice processando as entradas do log de operações (oplog).
61    fn update_index(
62        &mut self,
63        oplog: &Log,
64        _entries: &[Entry],
65    ) -> std::result::Result<(), Self::Error> {
66        let mut handled = HashSet::new();
67
68        // Usa um "write lock" para garantir acesso exclusivo durante a atualização.
69        let mut index = self.index.write();
70
71        // Itera sobre as entradas do log em ordem reversa para processar
72        // as operações mais recentes primeiro.
73        for entry in oplog.values().iter().rev() {
74            // Since payload is a String, not Option<String>, we check if it's not empty
75            if !entry.payload.is_empty() {
76                match serde_json::from_str::<Operation>(&entry.payload) {
77                    Ok(op_result) => {
78                        // Pula entradas sem chave.
79                        let key = match op_result.key() {
80                            Some(k) => k,
81                            None => continue,
82                        };
83
84                        // Processa cada chave apenas uma vez.
85                        if !handled.contains(key) {
86                            handled.insert(key.clone());
87
88                            match op_result.op() {
89                                "PUT" => {
90                                    let value = op_result.value();
91                                    if !value.is_empty() {
92                                        index.insert(key.clone(), value.to_vec());
93                                    }
94                                }
95                                "DEL" => {
96                                    index.remove(key);
97                                }
98                                _ => { /* ignora outras operações */ }
99                            }
100                        }
101                    }
102                    Err(e) => {
103                        return Err(GuardianError::Store(format!(
104                            "Erro ao parsear operação: {}",
105                            e
106                        )));
107                    }
108                }
109            }
110        }
111
112        Ok(())
113    }
114
115    /// Limpa todos os dados do índice.
116    fn clear(&mut self) -> std::result::Result<(), Self::Error> {
117        let mut index = self.index.write();
118        index.clear();
119        Ok(())
120    }
121}