chunk_store: use mutex

This commit is contained in:
Dietmar Maurer 2018-12-07 16:12:45 +01:00
parent 128b37feea
commit c5d82e5f34
1 changed files with 34 additions and 11 deletions

View File

@ -4,12 +4,14 @@ use std::io::Write;
use crypto::digest::Digest; use crypto::digest::Digest;
use crypto::sha2::Sha512Trunc256; use crypto::sha2::Sha512Trunc256;
use std::sync::Mutex;
pub struct ChunkStore { pub struct ChunkStore {
base: PathBuf, base: PathBuf,
chunk_dir: PathBuf, chunk_dir: PathBuf,
hasher: Sha512Trunc256, hasher: Sha512Trunc256,
mutex: Mutex<bool>,
} }
const HEX_CHARS: &'static [u8; 16] = b"0123456789abcdef"; const HEX_CHARS: &'static [u8; 16] = b"0123456789abcdef";
@ -53,9 +55,11 @@ impl ChunkStore {
let hasher = Sha512Trunc256::new(); let hasher = Sha512Trunc256::new();
ChunkStore { base, chunk_dir, hasher } ChunkStore { base, chunk_dir, hasher, mutex: Mutex::new(false) }
} }
// fixme: aquire filesystem lock for directory
pub fn create<P: Into<PathBuf>>(path: P) -> Result<Self, Error> { pub fn create<P: Into<PathBuf>>(path: P) -> Result<Self, Error> {
let me = Self::new(path); let me = Self::new(path);
@ -94,22 +98,40 @@ impl ChunkStore {
println!("DIGEST {}", u256_to_hex(&digest)); println!("DIGEST {}", u256_to_hex(&digest));
let mut chunk_path = self.base.clone(); let mut chunk_path = self.base.clone();
let prefix = u256_to_prefix(&digest); let prefix = u256_to_prefix(&digest);
chunk_path.push(prefix); chunk_path.push(&prefix);
let digest_str = u256_to_hex(&digest);
chunk_path.push(&digest_str);
if let Err(_e) = std::fs::create_dir(&chunk_path) { /* ignore */ } let lock = self.mutex.lock();
println!("PATH {:?}", chunk_path); if let Ok(metadata) = std::fs::metadata(&chunk_path) {
if metadata.is_file() {
return Ok(digest);
} else {
bail!("Got unexpected file type for chunk {}", digest_str);
}
}
chunk_path.push(u256_to_hex(&digest)); let mut chunk_dir = self.base.clone();
//chunk_path.set_extension("tmp"); chunk_dir.push(&prefix);
//chunk_path.set_extension("");
let mut f = std::fs::File::create(&chunk_path)?; if let Err(_) = std::fs::create_dir(&chunk_dir) { /* ignore */ }
let mut tmp_path = chunk_path.clone();
tmp_path.set_extension("tmp");
let mut f = std::fs::File::create(&tmp_path)?;
f.write_all(chunk)?; f.write_all(chunk)?;
if let Err(err) = std::fs::rename(&tmp_path, &chunk_path) {
if let Err(_) = std::fs::remove_file(&tmp_path) { /* ignore */ }
bail!("Atomic rename failed for chunk {} - {}", digest_str, err);
}
println!("PATH {:?}", chunk_path); println!("PATH {:?}", chunk_path);
drop(lock);
Ok(digest) Ok(digest)
} }
@ -125,7 +147,8 @@ fn test_chunk_store1() {
assert!(chunk_store.is_err()); assert!(chunk_store.is_err());
let mut chunk_store = ChunkStore::create(".testdir").unwrap(); let mut chunk_store = ChunkStore::create(".testdir").unwrap();
chunk_store.insert_chunk(&[0u8, 1u8]); chunk_store.insert_chunk(&[0u8, 1u8]).unwrap();
chunk_store.insert_chunk(&[0u8, 1u8]).unwrap();
let chunk_store = ChunkStore::create(".testdir"); let chunk_store = ChunkStore::create(".testdir");