//! Authors: Robert Lopez //! //! Basic example of persisting a Cache use serde::{Deserialize, Serialize}; use std::{collections::HashMap, future::Future, pin::Pin, sync::Arc}; use tokio::sync::Mutex; use walr::WAL; type Cache = HashMap; #[derive(Serialize, Deserialize)] enum CacheLog { Remove(String), Insert { key: String, value: String }, } impl CacheLog { fn inner(self) -> (String, Option) { match self { Self::Remove(key) => (key, None), Self::Insert { key, value } => (key, Some(value)), } } } #[tokio::main] async fn main() -> Result<(), Box> { fn replay_handler(logs: Vec, checkpoint: Arc>) -> ReplayHandlerResult { Box::pin(async move { let mut checkpoint = checkpoint.lock().await; for log in logs { match log { CacheLog::Insert { key, value } => checkpoint.insert(key, value), CacheLog::Remove(key) => checkpoint.remove(&key), }; } Ok(()) }) } let mut wal: WAL = WAL::open("./cache_wal", Box::new(replay_handler), None).await?; let mut cache = wal.replay().await?; let log = CacheLog::Insert { key: "some id".to_string(), value: "some data".to_string(), }; wal.log(&log).await?; let (key, value) = log.inner(); cache.insert(key, value.unwrap()); let mut logs = vec![]; for string in vec!["1".to_string(), "2".to_string()] { logs.push(CacheLog::Insert { key: string.clone(), value: string, }); } wal.log_many(&logs).await?; for log in logs { let (key, value) = log.inner(); cache.insert(key, value.unwrap()); } wal.checkpoint(&cache).await?; Ok(()) }