Mercurial > lbo > hg > leveldb-rs
view src/snapshot.rs @ 325:f39d34cf05e5
db_impl: Make VersionSet shared
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sun, 01 Oct 2017 20:36:48 +0200 |
parents | c8288b1ca724 |
children | 036e3084f8f0 |
line wrap: on
line source
use std::collections::HashMap; use types::{share, MAX_SEQUENCE_NUMBER, SequenceNumber, Shared}; /// Opaque snapshot handle; Represents index to SnapshotList.map type SnapshotHandle = u64; pub struct Snapshot { id: SnapshotHandle, sl: Shared<InnerSnapshotList>, } impl Drop for Snapshot { fn drop(&mut self) { self.sl.borrow_mut().delete(self.id); } } /// A list of all snapshots is kept in the DB. struct InnerSnapshotList { map: HashMap<SnapshotHandle, SequenceNumber>, newest: SnapshotHandle, oldest: SnapshotHandle, } pub struct SnapshotList { inner: Shared<InnerSnapshotList>, } impl SnapshotList { pub fn new() -> SnapshotList { SnapshotList { inner: share(InnerSnapshotList { map: HashMap::new(), newest: 0, oldest: 0, }), } } pub fn new_snapshot(&mut self, seq: SequenceNumber) -> Snapshot { let inner = self.inner.clone(); let mut sl = self.inner.borrow_mut(); sl.newest += 1; let newest = sl.newest; sl.map.insert(newest, seq); if sl.oldest == 0 { sl.oldest = sl.newest; } Snapshot { id: sl.newest, sl: inner, } } pub fn sequence_at(&self, ss: &Snapshot) -> Option<SequenceNumber> { let sl = self.inner.borrow_mut(); sl.map.get(&ss.id).map(|sn| *sn) } /// oldest returns the lowest sequence number of all snapshots. It returns 0 if no snapshots /// are present. pub fn oldest(&self) -> SequenceNumber { let oldest = self.inner.borrow().map.iter().fold(MAX_SEQUENCE_NUMBER, |s, (seq, _)| if *seq < s { *seq } else { s }); if oldest == MAX_SEQUENCE_NUMBER { 0 } else { oldest } } /// newest returns the newest sequence number of all snapshots. If no snapshots are present, it /// returns 0. pub fn newest(&self) -> SequenceNumber { self.inner.borrow().map.iter().fold(0, |s, (seq, _)| if *seq > s { *seq } else { s }) } pub fn empty(&self) -> bool { self.inner.borrow().oldest == 0 } } impl InnerSnapshotList { fn delete(&mut self, id: SnapshotHandle) { self.map.remove(&id); } } #[cfg(test)] mod tests { use super::*; #[allow(unused_variables)] #[test] fn test_snapshot_list() { let mut l = SnapshotList::new(); { assert!(l.empty()); let a = l.new_snapshot(1); { let b = l.new_snapshot(2); { let c = l.new_snapshot(3); assert!(!l.empty()); assert_eq!(l.oldest(), 1); assert_eq!(l.newest(), 3); } assert_eq!(l.newest(), 2); assert_eq!(l.oldest(), 1); } assert_eq!(l.oldest(), 1); } assert_eq!(l.oldest(), 0); } }