use crate::guardian::error::GuardianError;
use crate::log::{Log, entry::Entry};
use crate::traits::StoreIndex;
use std::collections::{HashMap, HashSet};
use std::sync::RwLock;
pub struct BaseIndex {
id: Vec<u8>,
index: RwLock<HashMap<String, Vec<u8>>>,
}
pub fn new_base_index(
public_key: Vec<u8>,
) -> Box<dyn StoreIndex<Error = GuardianError> + Send + Sync> {
Box::new(BaseIndex {
id: public_key,
index: RwLock::new(HashMap::new()),
})
}
impl StoreIndex for BaseIndex {
type Error = GuardianError;
fn contains_key(&self, key: &str) -> Result<bool, Self::Error> {
let index_lock = self.index.read().map_err(|e| {
GuardianError::Store(format!("Falha ao adquirir lock de leitura: {}", e))
})?;
Ok(index_lock.contains_key(key))
}
fn get_bytes(&self, key: &str) -> Result<Option<Vec<u8>>, Self::Error> {
let index_lock = self.index.read().map_err(|e| {
GuardianError::Store(format!("Falha ao adquirir lock de leitura: {}", e))
})?;
Ok(index_lock.get(key).cloned())
}
fn keys(&self) -> Result<Vec<String>, Self::Error> {
let index_lock = self.index.read().map_err(|e| {
GuardianError::Store(format!("Falha ao adquirir lock de leitura: {}", e))
})?;
Ok(index_lock.keys().cloned().collect())
}
fn len(&self) -> Result<usize, Self::Error> {
let index_lock = self.index.read().map_err(|e| {
GuardianError::Store(format!("Falha ao adquirir lock de leitura: {}", e))
})?;
Ok(index_lock.len())
}
fn is_empty(&self) -> Result<bool, Self::Error> {
let index_lock = self.index.read().map_err(|e| {
GuardianError::Store(format!("Falha ao adquirir lock de leitura: {}", e))
})?;
Ok(index_lock.is_empty())
}
fn update_index(&mut self, _log: &Log, entries: &[Entry]) -> Result<(), Self::Error> {
let mut handled = HashSet::new();
let mut index = self.index.write().map_err(|e| {
GuardianError::Store(format!("Falha ao adquirir lock de escrita: {}", e))
})?;
for entry in entries.iter().rev() {
let operation = match crate::stores::operation::parse_operation(entry.clone()) {
Ok(op) => op,
Err(e) => {
eprintln!("Aviso: Erro ao parsear operação: {}", e);
continue;
}
};
let key = match operation.key() {
Some(k) if !k.is_empty() => k,
_ => continue, };
if handled.contains(key) {
continue;
}
handled.insert(key.clone());
match operation.op() {
"PUT" => {
let value = operation.value();
if !value.is_empty() {
index.insert(key.clone(), value.to_vec());
}
}
"DEL" => {
index.remove(key);
}
_ => {
eprintln!("Aviso: Operação desconhecida ignorada: {}", operation.op());
}
}
}
Ok(())
}
fn clear(&mut self) -> Result<(), Self::Error> {
let mut index_lock = self.index.write().map_err(|e| {
GuardianError::Store(format!("Falha ao adquirir lock de escrita: {}", e))
})?;
index_lock.clear();
Ok(())
}
}
impl BaseIndex {
pub fn id(&self) -> &[u8] {
&self.id
}
pub fn get_value(&self, key: &str) -> Result<Option<Vec<u8>>, GuardianError> {
self.get_bytes(key)
}
}