diff --git a/src/backup/chunk_store.rs b/src/backup/chunk_store.rs new file mode 100644 index 00000000..d376a5b4 --- /dev/null +++ b/src/backup/chunk_store.rs @@ -0,0 +1,74 @@ +use failure::*; +use std::path::{Path, PathBuf}; + +pub struct ChunkStore { + base: PathBuf, + chunk_dir: PathBuf, +} + +// see RFC4648 for base32hex definition +const BASE32HEX_ALPHABET: &'static [u8; 32] = b"0123456789ABCDEFGHIJKLMNOPQRSTUV"; + +fn u10_to_base32hex(num: usize) -> String { + let lo = num & 0b11111 as usize; + let hi = num >> 5 as usize; + format!("{}{}", BASE32HEX_ALPHABET[hi] as char, BASE32HEX_ALPHABET[lo] as char) +} + +impl ChunkStore { + + fn new>(path: P) -> Self { + let base = path.into(); + let mut chunk_dir = base.clone(); + chunk_dir.push(".chunks"); + + ChunkStore { base, chunk_dir } + } + + pub fn create>(path: P) -> Result { + + let me = Self::new(path); + + std::fs::create_dir(&me.base)?; + std::fs::create_dir(&me.chunk_dir)?; + + // create 1024 subdir + for i in 0..1024 { + let mut l1path = me.base.clone(); + l1path.push(u10_to_base32hex(i)); + std::fs::create_dir(&l1path)?; + } + + Ok(me) + } + + pub fn open>(path: P) -> Result { + + let me = Self::new(path); + + let metadata = std::fs::metadata(&me.chunk_dir)?; + + println!("{:?}", metadata.file_type()); + + Ok(me) + } + +} + + +#[test] +fn test_chunk_store1() { + + if let Err(_e) = std::fs::remove_dir_all(".testdir") { /* ignore */ } + + let chunk_store = ChunkStore::open(".testdir"); + assert!(chunk_store.is_err()); + + let chunk_store = ChunkStore::create(".testdir"); + assert!(chunk_store.is_ok()); + + let chunk_store = ChunkStore::create(".testdir"); + assert!(chunk_store.is_err()); + + +} diff --git a/src/lib.rs b/src/lib.rs index 2410a8a0..0d800d05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,6 +30,11 @@ pub mod server { pub mod section_config; +pub mod backup { + + pub mod chunk_store; +} + pub mod storage { pub mod config;