use crate::guardian::error::GuardianError;
use crate::log::{Log, entry::Entry};
use crate::stores::operation::Operation;
use crate::traits::StoreIndex;
use parking_lot::RwLock;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
pub struct KvIndex {
index: Arc<RwLock<HashMap<String, Vec<u8>>>>,
}
impl Default for KvIndex {
fn default() -> Self {
Self::new()
}
}
impl KvIndex {
pub fn new() -> Self {
KvIndex {
index: Arc::new(RwLock::new(HashMap::new())),
}
}
}
impl StoreIndex for KvIndex {
type Error = GuardianError;
fn contains_key(&self, key: &str) -> std::result::Result<bool, Self::Error> {
let index = self.index.read();
Ok(index.contains_key(key))
}
fn get_bytes(&self, key: &str) -> std::result::Result<Option<Vec<u8>>, Self::Error> {
let index = self.index.read();
Ok(index.get(key).cloned())
}
fn keys(&self) -> std::result::Result<Vec<String>, Self::Error> {
let index = self.index.read();
Ok(index.keys().cloned().collect())
}
fn len(&self) -> std::result::Result<usize, Self::Error> {
let index = self.index.read();
Ok(index.len())
}
fn is_empty(&self) -> std::result::Result<bool, Self::Error> {
let index = self.index.read();
Ok(index.is_empty())
}
fn update_index(
&mut self,
oplog: &Log,
_entries: &[Entry],
) -> std::result::Result<(), Self::Error> {
let mut handled = HashSet::new();
let mut index = self.index.write();
for entry in oplog.values().iter().rev() {
if !entry.payload.is_empty() {
match crate::guardian::serializer::deserialize::<Operation>(&entry.payload) {
Ok(op_result) => {
let key = match op_result.key() {
Some(k) => k,
None => continue,
};
if !handled.contains(key) {
handled.insert(key.clone());
match op_result.op() {
"PUT" => {
let value = op_result.value();
if !value.is_empty() {
index.insert(key.clone(), value.to_vec());
}
}
"DEL" => {
index.remove(key);
}
_ => { }
}
}
}
Err(e) => {
return Err(GuardianError::Store(format!(
"Erro ao parsear operação: {}",
e
)));
}
}
}
}
Ok(())
}
fn clear(&mut self) -> std::result::Result<(), Self::Error> {
let mut index = self.index.write();
index.clear();
Ok(())
}
}