1extern crate bincode;
2extern crate serde;
3
4use bincode::SizeLimit;
5use bincode::serde::{DeserializeError, deserialize_from, SerializeError, serialize_into};
6use serde::{Serialize, Deserialize};
7use std::{error, fmt, io};
8use std::cmp::Eq;
9use std::collections::hash_map::HashMap;
10use std::hash::Hash;
11use std::io::{Read, Write, Seek, SeekFrom, ErrorKind as IoErrorKind};
12use std::marker::PhantomData;
13
14#[derive(Debug)]
15pub enum LogKvError {
16 Io(io::Error),
17 SerializeError(SerializeError),
18 DeserializeError(DeserializeError),
19}
20
21impl fmt::Display for LogKvError {
22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23 match *self {
24 LogKvError::Io(ref err) => write!(f, "IO error: {}", err),
25 LogKvError::SerializeError(ref err) => write!(f, "Encoding error: {}", err),
26 LogKvError::DeserializeError(ref err) => write!(f, "Decoding error: {}", err),
27 }
28 }
29}
30
31impl error::Error for LogKvError {
32 fn description(&self) -> &str {
33 match *self {
34 LogKvError::Io(ref err) => err.description(),
35 LogKvError::SerializeError(ref err) => err.description(),
36 LogKvError::DeserializeError(ref err) => err.description(),
37 }
38 }
39
40 fn cause(&self) -> Option<&error::Error> {
41 match *self {
42 LogKvError::Io(ref err) => Some(err),
43 LogKvError::SerializeError(ref err) => Some(err),
44 LogKvError::DeserializeError(ref err) => Some(err),
45 }
46 }
47}
48
49impl From<io::Error> for LogKvError {
50 fn from(err: io::Error) -> LogKvError {
51 LogKvError::Io(err)
52 }
53}
54
55impl From<SerializeError> for LogKvError {
56 fn from(err: SerializeError) -> LogKvError {
57 LogKvError::SerializeError(err)
58 }
59}
60
61impl From<DeserializeError> for LogKvError {
62 fn from(err: DeserializeError) -> LogKvError {
63 LogKvError::DeserializeError(err)
64 }
65}
66
67pub struct LogKv<K, V, T> {
68 cursor: T,
69 index: HashMap<K, u64>,
70 _phantom: PhantomData<V>,
71}
72
73impl<K, V, T> LogKv<K, V, T>
74 where K: Serialize + Deserialize + Eq + Hash,
75 V: Serialize + Deserialize,
76 T: Read + Write + Seek
77{
78 pub fn create(cursor: T) -> Result<LogKv<K, V, T>, LogKvError> {
79 let mut logkv = LogKv {
80 cursor: cursor,
81 index: HashMap::new(),
82 _phantom: PhantomData,
83 };
84
85 logkv.cursor.seek(SeekFrom::Start(0))?;
86 loop {
87 let key = match deserialize_from::<T, K>(&mut logkv.cursor, SizeLimit::Infinite) {
88 Ok(key) => key,
89 Err(DeserializeError::IoError(ref e)) if e.kind() == IoErrorKind::UnexpectedEof => {
90 break;
91 }
92 Err(e) => return Err(LogKvError::from(e)),
93 };
94
95 let position = logkv.cursor.seek(SeekFrom::Current(0))?;
96 logkv.index.insert(key, position);
97 deserialize_from::<T, V>(&mut logkv.cursor, SizeLimit::Infinite)?;
98 }
99
100 Ok(logkv)
101 }
102
103 pub fn put<L : Into<K>, W : Into<V>>(&mut self, key: L, value: W) -> Result<(), LogKvError> {
118 let serialize_key = key.into();
119 serialize_into(&mut self.cursor, &serialize_key, SizeLimit::Infinite)?;
120 let position = self.cursor.seek(SeekFrom::Current(0))?;
121 self.index.insert(serialize_key, position);
122 serialize_into(&mut self.cursor, &value.into(), SizeLimit::Infinite)?;
123 Ok(())
124 }
125
126 pub fn get<L : Into<K>>(&mut self, key: L) -> Result<Option<V>, LogKvError> {
146 return match self.index.get(&key.into()) {
147 Some(position) => {
148 self.cursor.seek(SeekFrom::Start(*position))?;
149 let value = deserialize_from(&mut self.cursor, SizeLimit::Infinite)?;
150 Ok(Some(value))
151 }
152 None => Ok(None),
153 };
154 }
155}