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 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
use std::fmt; use std::fs; use std::io; use std::io::prelude::*; use std::path::PathBuf; use std::ops::{Deref, DerefMut}; use std::sync::{Arc, Mutex, MutexGuard}; use rustc_serialize::{Encodable, Decodable}; use bincode::SizeLimit; use bincode::rustc_serialize::{encode, decode, DecodingResult}; fn to_binary<T: Encodable>(s: &T) -> Vec<u8> { encode(s, SizeLimit::Infinite).unwrap() } fn from_binary<T: Decodable>(encoded: Vec<u8>) -> DecodingResult<T> { decode(&encoded[..]) } #[derive(Debug, Clone)] pub struct Persistent<T: Encodable + Decodable> { pub inner: Arc<Mutex<T>>, pub name: String, } impl<T: Encodable + Decodable> Persistent<T> { pub fn handle<'a>(&'a self) -> Txn<'a, T> { let mut inner = self.inner.lock().unwrap(); if let Some(read) = self.read() { *inner = read; } Txn { inner: inner, name: self.name.clone(), } } fn read(&self) -> Option<T> { if let Ok(mut f) = fs::File::open(self.path()) { let mut s = vec![]; f.read_to_end(&mut s).unwrap(); from_binary(s).ok().or_else(|| None) } else { None } } fn path(&self) -> PathBuf { self.name.clone().into() } fn clear(&self) -> io::Result<()> { fs::remove_file(self.path()) } } impl<'a, T: 'a + Encodable + Decodable> Txn<'a, T> { fn path(&self) -> PathBuf { self.name.clone().into() } fn write(&self) -> io::Result<()> { let bytes = to_binary(&*self.inner); from_binary::<T>(bytes.clone()).unwrap(); let mut f = fs::File::create(self.path()).unwrap(); let res = f.write_all(&*bytes); f.sync_all(); res } } pub struct Txn<'a, T: 'a + Encodable + Decodable> { pub inner: MutexGuard<'a, T>, pub name: String, } impl<'a, T: Encodable + Decodable + fmt::Debug> fmt::Debug for Txn<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Txn {{ inner: {:?} }}", *self.inner) } } impl<'a, T: Encodable + Decodable> Drop for Txn<'a, T> { fn drop(&mut self) { self.write(); } } impl<'a, T: 'a + Encodable + Decodable> Deref for Txn<'a, T> { type Target = MutexGuard<'a, T>; fn deref(&self) -> &MutexGuard<'a, T> { &self.inner } } impl<'a, T: 'a + Encodable + Decodable> DerefMut for Txn<'a, T> { fn deref_mut(&mut self) -> &mut MutexGuard<'a, T> { &mut self.inner } }