1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use super::{Ballot, Entry};
use crate::Index;
use anyhow::Result;
use std::collections::BTreeMap;
use std::sync::Arc;
use tokio::sync::{Mutex, RwLock};
pub struct Storage {
entries: Arc<RwLock<BTreeMap<u64, super::Entry>>>,
ballot: Arc<Mutex<Ballot>>,
}
impl Storage {
pub fn new() -> Self {
Self {
entries: Arc::new(RwLock::new(BTreeMap::new())),
ballot: Arc::new(Mutex::new(Ballot::new())),
}
}
}
#[async_trait::async_trait]
impl super::RaftStorage for Storage {
async fn get_head_index(&self) -> Result<Index> {
let x = self.entries.read().await;
let r = match x.iter().next() {
Some((k, _)) => *k,
None => 0,
};
Ok(r)
}
async fn get_last_index(&self) -> Result<Index> {
let x = self.entries.read().await;
let r = match x.iter().next_back() {
Some((k, _)) => *k,
None => 0,
};
Ok(r)
}
async fn delete_entry(&self, i: Index) -> Result<()> {
self.entries.write().await.remove(&i);
Ok(())
}
async fn insert_entry(&self, i: Index, e: Entry) -> Result<()> {
self.entries.write().await.insert(i, e);
Ok(())
}
async fn get_entry(&self, i: Index) -> Result<Option<Entry>> {
let r = self.entries.read().await.get(&i).cloned();
Ok(r)
}
async fn save_ballot(&self, v: Ballot) -> Result<()> {
*self.ballot.lock().await = v;
Ok(())
}
async fn load_ballot(&self) -> Result<Ballot> {
let r = self.ballot.lock().await.clone();
Ok(r)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::storage;
#[tokio::test]
async fn test_mem_storage() -> Result<()> {
let s = Storage::new();
storage::test_storage(s).await?;
Ok(())
}
}