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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use std::collections::HashMap;
use std::fmt;
use std::io;
use std::sync::{RwLock, Arc};
use failure::Backtrace;
use dir_signature::get_hash;
use futures::{Future};
use futures::future::{FutureResult, ok, err};
pub use id::ImageId;
pub trait GetIndex {
type Data: AsRef<[u8]>;
type Error: fmt::Display;
type Future: Future<Item=Self::Data, Error=Self::Error> + 'static;
fn read_index(&self, id: &ImageId) -> Self::Future;
}
fn _object_safe() {
use futures::future::FutureResult;
let _: Option<&GetIndex<Data=Vec<u8>, Error=String,
Future=FutureResult<Vec<u8>, String>>> = None;
}
#[derive(Debug, Clone)]
pub struct InMemoryIndexes {
indexes: Arc<RwLock<HashMap<ImageId, Arc<[u8]>>>>,
}
#[derive(Debug, Fail)]
pub enum IndexError {
#[doc(hidden)]
#[fail(display="error parsing index")]
ParseError,
#[doc(hidden)]
#[fail(display="index lock was poisoned")]
LockError(Backtrace),
#[doc(hidden)]
#[fail(display="non-existent-error")]
__Nonexhaustive,
}
#[derive(Debug, Fail)]
pub enum ReadError {
#[fail(display="index {} with not found", _0)]
NotFound(ImageId),
#[doc(hidden)]
#[fail(display="index lock was poisoned")]
LockError(Backtrace),
#[doc(hidden)]
#[fail(display="non-existent-error")]
__Nonexhaustive,
}
impl InMemoryIndexes {
pub fn new() -> InMemoryIndexes {
InMemoryIndexes {
indexes: Arc::new(RwLock::new(HashMap::new())),
}
}
pub fn register_index(&self, data: &[u8]) -> Result<ImageId, IndexError> {
let image_id = ImageId::from(get_hash(&mut io::Cursor::new(&data))
.map_err(|_| IndexError::ParseError)?);
let mut indexes = self.indexes.write()
.map_err(|_| IndexError::LockError(Backtrace::new()))?;
indexes.insert(image_id.clone(), Arc::from(data));
Ok(image_id)
}
}
impl GetIndex for InMemoryIndexes {
type Data = Arc<[u8]>;
type Error = ReadError;
type Future = FutureResult<Arc<[u8]>, ReadError>;
fn read_index(&self, id: &ImageId) -> Self::Future {
let data = match self.indexes.read() {
Ok(data) => data,
Err(_) => return err(ReadError::LockError(Backtrace::new())),
};
match data.get(id) {
Some(data) => ok(data.clone()),
None => err(ReadError::NotFound(id.clone())),
}
}
}