impl sweep_used_chunks, first try
This commit is contained in:
		@ -25,6 +25,7 @@ hyper = "0.12.14"
 | 
				
			|||||||
lazy_static = "1.1.0"
 | 
					lazy_static = "1.1.0"
 | 
				
			||||||
regex = "1.0.6"
 | 
					regex = "1.0.6"
 | 
				
			||||||
rust-crypto = "0.2.36"
 | 
					rust-crypto = "0.2.36"
 | 
				
			||||||
 | 
					libc = "0.2"
 | 
				
			||||||
nix = "0.12.0"
 | 
					nix = "0.12.0"
 | 
				
			||||||
shellwords = "1.0.0"
 | 
					shellwords = "1.0.0"
 | 
				
			||||||
uuid = { version = "0.7", features = ["v4"] }
 | 
					uuid = { version = "0.7", features = ["v4"] }
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ pub struct ChunkStore {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const HEX_CHARS: &'static [u8; 16] = b"0123456789abcdef";
 | 
					const HEX_CHARS: &'static [u8; 16] = b"0123456789abcdef";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn u256_to_hex(digest: &[u8]) -> String {
 | 
					pub fn digest_to_hex(digest: &[u8]) -> String {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut buf = Vec::<u8>::with_capacity(digest.len()*2);
 | 
					    let mut buf = Vec::<u8>::with_capacity(digest.len()*2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,7 +32,7 @@ pub fn u256_to_hex(digest: &[u8]) -> String {
 | 
				
			|||||||
    unsafe { String::from_utf8_unchecked(buf) }
 | 
					    unsafe { String::from_utf8_unchecked(buf) }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn u256_to_prefix(digest: &[u8]) -> PathBuf {
 | 
					fn digest_to_prefix(digest: &[u8]) -> PathBuf {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut buf = Vec::<u8>::with_capacity(3+1+2+1);
 | 
					    let mut buf = Vec::<u8>::with_capacity(3+1+2+1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -153,18 +153,66 @@ impl ChunkStore {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub fn touch_chunk(&mut self, digest:&[u8]) ->  Result<(), Error> {
 | 
					    pub fn touch_chunk(&mut self, digest:&[u8]) ->  Result<(), Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // fixme:  nix::sys::stat::utimensat
 | 
				
			||||||
        let mut chunk_path = self.chunk_dir.clone();
 | 
					        let mut chunk_path = self.chunk_dir.clone();
 | 
				
			||||||
        let prefix = u256_to_prefix(&digest);
 | 
					        let prefix = digest_to_prefix(&digest);
 | 
				
			||||||
        chunk_path.push(&prefix);
 | 
					        chunk_path.push(&prefix);
 | 
				
			||||||
        let digest_str = u256_to_hex(&digest);
 | 
					        let digest_str = digest_to_hex(&digest);
 | 
				
			||||||
        chunk_path.push(&digest_str);
 | 
					        chunk_path.push(&digest_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::fs::metadata(&chunk_path)?;
 | 
					        std::fs::metadata(&chunk_path)?;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn sweep_old_files(&self, dir: &Path) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut handle = match nix::dir::Dir::open(
 | 
				
			||||||
 | 
					            dir, nix::fcntl::OFlag::O_RDONLY, nix::sys::stat::Mode::empty()) {
 | 
				
			||||||
 | 
					            Ok(h) => h,
 | 
				
			||||||
 | 
					            Err(_) => return,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let rawfd = handle.as_raw_fd();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let now = unsafe { libc::time(std::ptr::null_mut()) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for entry in handle.iter() {
 | 
				
			||||||
 | 
					             match entry {
 | 
				
			||||||
 | 
					                Ok(entry) => {
 | 
				
			||||||
 | 
					                    if let Some(file_type) = entry.file_type() {
 | 
				
			||||||
 | 
					                        if file_type == nix::dir::Type::File {
 | 
				
			||||||
 | 
					                            let filename = entry.file_name();
 | 
				
			||||||
 | 
					                            if let Ok(stat) = nix::sys::stat::fstatat(rawfd, filename, nix::fcntl::AtFlags::AT_SYMLINK_NOFOLLOW) {
 | 
				
			||||||
 | 
					                                let age = now - stat.st_atime;
 | 
				
			||||||
 | 
					                                println!("FOUND {}  {:?}", age/(3600*24), filename);
 | 
				
			||||||
 | 
					                                if age/(3600*24) >= 2 {
 | 
				
			||||||
 | 
					                                    println!("UNLINK {}  {:?}", age/(3600*24), filename);
 | 
				
			||||||
 | 
					                                    unsafe { libc::unlinkat(rawfd, filename.as_ptr(), 0); }
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Err(_) => {
 | 
				
			||||||
 | 
					                    // fixme ??
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					             }
 | 
				
			||||||
 | 
					         }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn sweep_used_chunks(&mut self) -> Result<(), Error> {
 | 
					    pub fn sweep_used_chunks(&mut self) -> Result<(), Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i in 0..4096 {
 | 
				
			||||||
 | 
					            let mut l1path = self.chunk_dir.clone();
 | 
				
			||||||
 | 
					            l1path.push(format!("{:03x}", i));
 | 
				
			||||||
 | 
					            for j in 0..256 {
 | 
				
			||||||
 | 
					                let mut l2path = l1path.clone();
 | 
				
			||||||
 | 
					                l2path.push(format!("{:02x}", j));
 | 
				
			||||||
 | 
					                self.sweep_old_files(&l2path);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -175,12 +223,12 @@ impl ChunkStore {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let mut digest = [0u8; 32];
 | 
					        let mut digest = [0u8; 32];
 | 
				
			||||||
        self.hasher.result(&mut digest);
 | 
					        self.hasher.result(&mut digest);
 | 
				
			||||||
        //println!("DIGEST {}", u256_to_hex(&digest));
 | 
					        //println!("DIGEST {}", digest_to_hex(&digest));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut chunk_path = self.chunk_dir.clone();
 | 
					        let mut chunk_path = self.chunk_dir.clone();
 | 
				
			||||||
        let prefix = u256_to_prefix(&digest);
 | 
					        let prefix = digest_to_prefix(&digest);
 | 
				
			||||||
        chunk_path.push(&prefix);
 | 
					        chunk_path.push(&prefix);
 | 
				
			||||||
        let digest_str = u256_to_hex(&digest);
 | 
					        let digest_str = digest_to_hex(&digest);
 | 
				
			||||||
        chunk_path.push(&digest_str);
 | 
					        chunk_path.push(&digest_str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let lock = self.mutex.lock();
 | 
					        let lock = self.mutex.lock();
 | 
				
			||||||
 | 
				
			|||||||
@ -111,7 +111,7 @@ impl <'a> ImageIndexReader<'a> {
 | 
				
			|||||||
            let digest = unsafe { std::slice::from_raw_parts_mut(self.index.add(pos*32), 32) };
 | 
					            let digest = unsafe { std::slice::from_raw_parts_mut(self.index.add(pos*32), 32) };
 | 
				
			||||||
            if let Err(err) = self.store.touch_chunk(digest) {
 | 
					            if let Err(err) = self.store.touch_chunk(digest) {
 | 
				
			||||||
                bail!("unable to access chunk {}, required by {:?} - {}",
 | 
					                bail!("unable to access chunk {}, required by {:?} - {}",
 | 
				
			||||||
                      u256_to_hex(digest), self.filename, err);
 | 
					                      digest_to_hex(digest), self.filename, err);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -262,7 +262,7 @@ impl <'a> ImageIndexWriter<'a> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        let (is_duplicate, digest) = self.store.insert_chunk(chunk)?;
 | 
					        let (is_duplicate, digest) = self.store.insert_chunk(chunk)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        println!("ADD CHUNK {} {} {} {}", pos, chunk.len(), is_duplicate,  u256_to_hex(&digest));
 | 
					        println!("ADD CHUNK {} {} {} {}", pos, chunk.len(), is_duplicate,  digest_to_hex(&digest));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let index_pos = (pos/self.chunk_size)*32;
 | 
					        let index_pos = (pos/self.chunk_size)*32;
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user