src/api2/admin/datastore/backup/environment.rs: register/lookup known chunks
This commit is contained in:
parent
97f03eff13
commit
a09c0e38d8
|
@ -261,11 +261,10 @@ fn dynamic_append (
|
||||||
|
|
||||||
let env: &BackupEnvironment = rpcenv.as_ref();
|
let env: &BackupEnvironment = rpcenv.as_ref();
|
||||||
|
|
||||||
let _size = 0;
|
let digest = crate::tools::hex_to_digest(digest_str)?;
|
||||||
let _digest = crate::tools::hex_to_digest(digest_str)?;
|
let size = env.lookup_chunk(&digest).ok_or_else(|| format_err!("no such chunk"))?;
|
||||||
|
|
||||||
// fixme: lookup digest and chunk size, then add
|
env.dynamic_writer_append_chunk(wid, size, &digest)?;
|
||||||
//env.dynamic_writer_append_chunk(wid, size, &digest)?;
|
|
||||||
|
|
||||||
env.log(format!("sucessfully added chunk {} to dynamic index {}", digest_str, wid));
|
env.log(format!("sucessfully added chunk {} to dynamic index {}", digest_str, wid));
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ struct SharedBackupState {
|
||||||
finished: bool,
|
finished: bool,
|
||||||
uid_counter: usize,
|
uid_counter: usize,
|
||||||
dynamic_writers: HashMap<usize, (u64 /* offset */, DynamicIndexWriter)>,
|
dynamic_writers: HashMap<usize, (u64 /* offset */, DynamicIndexWriter)>,
|
||||||
|
known_chunks: HashMap<[u8;32], u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SharedBackupState {
|
impl SharedBackupState {
|
||||||
|
@ -61,6 +62,7 @@ impl BackupEnvironment {
|
||||||
finished: false,
|
finished: false,
|
||||||
uid_counter: 0,
|
uid_counter: 0,
|
||||||
dynamic_writers: HashMap::new(),
|
dynamic_writers: HashMap::new(),
|
||||||
|
known_chunks: HashMap::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -76,6 +78,27 @@ impl BackupEnvironment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register a Chunk with associated length. A client may only use registered
|
||||||
|
// chunks (we do not trust clients that far ...)
|
||||||
|
pub fn register_chunk(&self, digest: [u8; 32], length: u32) -> Result<(), Error> {
|
||||||
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
|
state.ensure_unfinished()?;
|
||||||
|
|
||||||
|
state.known_chunks.insert(digest, length);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lookup_chunk(&self, digest: &[u8; 32]) -> Option<u32> {
|
||||||
|
let state = self.state.lock().unwrap();
|
||||||
|
|
||||||
|
match state.known_chunks.get(digest) {
|
||||||
|
Some(len) => Some(*len),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Store the writer with an unique ID
|
/// Store the writer with an unique ID
|
||||||
pub fn register_dynamic_writer(&self, writer: DynamicIndexWriter) -> Result<usize, Error> {
|
pub fn register_dynamic_writer(&self, writer: DynamicIndexWriter) -> Result<usize, Error> {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
@ -90,7 +113,7 @@ impl BackupEnvironment {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Append chunk to dynamic writer
|
/// Append chunk to dynamic writer
|
||||||
pub fn dynamic_writer_append_chunk(&self, wid: usize, size: u64, digest: &[u8; 32]) -> Result<(), Error> {
|
pub fn dynamic_writer_append_chunk(&self, wid: usize, size: u32, digest: &[u8; 32]) -> Result<(), Error> {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
state.ensure_unfinished()?;
|
state.ensure_unfinished()?;
|
||||||
|
@ -100,7 +123,7 @@ impl BackupEnvironment {
|
||||||
None => bail!("dynamic writer '{}' not registered", wid),
|
None => bail!("dynamic writer '{}' not registered", wid),
|
||||||
};
|
};
|
||||||
|
|
||||||
data.0 += size;
|
data.0 += size as u64;
|
||||||
|
|
||||||
data.1.add_chunk(data.0, digest)?;
|
data.1.add_chunk(data.0, digest)?;
|
||||||
|
|
||||||
|
|
|
@ -16,22 +16,22 @@ use super::environment::*;
|
||||||
pub struct UploadChunk {
|
pub struct UploadChunk {
|
||||||
stream: Body,
|
stream: Body,
|
||||||
store: Arc<DataStore>,
|
store: Arc<DataStore>,
|
||||||
size: u64,
|
size: u32,
|
||||||
chunk: Vec<u8>,
|
chunk: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UploadChunk {
|
impl UploadChunk {
|
||||||
|
|
||||||
pub fn new(stream: Body, store: Arc<DataStore>, size: u64) -> Self {
|
pub fn new(stream: Body, store: Arc<DataStore>, size: u32) -> Self {
|
||||||
Self { stream, store, size, chunk: vec![] }
|
Self { stream, store, size, chunk: vec![] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Future for UploadChunk {
|
impl Future for UploadChunk {
|
||||||
type Item = ([u8; 32], u64);
|
type Item = ([u8; 32], u32);
|
||||||
type Error = failure::Error;
|
type Error = failure::Error;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<([u8; 32], u64), failure::Error> {
|
fn poll(&mut self) -> Poll<([u8; 32], u32), failure::Error> {
|
||||||
loop {
|
loop {
|
||||||
match try_ready!(self.stream.poll()) {
|
match try_ready!(self.stream.poll()) {
|
||||||
Some(chunk) => {
|
Some(chunk) => {
|
||||||
|
@ -77,19 +77,20 @@ fn upload_dynamic_chunk(
|
||||||
rpcenv: Box<RpcEnvironment>,
|
rpcenv: Box<RpcEnvironment>,
|
||||||
) -> Result<BoxFut, Error> {
|
) -> Result<BoxFut, Error> {
|
||||||
|
|
||||||
let size = tools::required_integer_param(¶m, "size")?;
|
let size = tools::required_integer_param(¶m, "size")? as u32;
|
||||||
let wid = tools::required_integer_param(¶m, "wid")? as usize;
|
let wid = tools::required_integer_param(¶m, "wid")? as usize;
|
||||||
|
|
||||||
|
|
||||||
let env: &BackupEnvironment = rpcenv.as_ref();
|
let env: &BackupEnvironment = rpcenv.as_ref();
|
||||||
|
|
||||||
let upload = UploadChunk::new(req_body, env.datastore.clone(), size as u64);
|
let upload = UploadChunk::new(req_body, env.datastore.clone(), size);
|
||||||
|
|
||||||
let resp = upload
|
let resp = upload
|
||||||
.then(move |result| {
|
.then(move |result| {
|
||||||
let env: &BackupEnvironment = rpcenv.as_ref();
|
let env: &BackupEnvironment = rpcenv.as_ref();
|
||||||
|
|
||||||
let result = result.and_then(|(digest, size)| {
|
let result = result.and_then(|(digest, size)| {
|
||||||
|
env.register_chunk(digest, size)?;
|
||||||
env.dynamic_writer_append_chunk(wid, size, &digest)?;
|
env.dynamic_writer_append_chunk(wid, size, &digest)?;
|
||||||
Ok(json!(tools::digest_to_hex(&digest)))
|
Ok(json!(tools::digest_to_hex(&digest)))
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue