From 89704c61212d91c639dda3d812690909cca3fb36 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Sat, 29 Aug 2020 22:09:29 +0200 Subject: pkgs/profpatsch: add lru-dir --- pkgs/profpatsch/lru.nix | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 pkgs/profpatsch/lru.nix (limited to 'pkgs/profpatsch/lru.nix') diff --git a/pkgs/profpatsch/lru.nix b/pkgs/profpatsch/lru.nix new file mode 100644 index 00000000..e62bd29e --- /dev/null +++ b/pkgs/profpatsch/lru.nix @@ -0,0 +1,73 @@ +{ pkgs, writeRustSimple }: + +let + + # Given a directory, finds all files directly in that directory. + # If the size of all files (ignoring symlinks and directories) + # is bigger than MAX_SIZE, delete the 25% files with oldest mtime. + # + # Only deletes + lru-dir = writeRustSimple "lru-dir" {} (pkgs.writeText "main.rs" '' + use std::fs; + use std::convert::identity; + use std::path::Path; + + const MAX_SIZE : usize = 200 * 1000*1000; // 200 MB + + fn main() -> std::io::Result<()> { + let mut args = std::env::args_os(); + let dir = args.nth(1).unwrap(); + // only files, only in dir + // ignore all files that can’t be read + let mut files = std::fs::read_dir(&dir)? + .filter_map(|f| f.ok()) + .filter_map(|f| f.metadata().ok() + .map(|m| (f.path(), m))) + .filter(|f| f.1.is_file()) + .collect::>(); + let size : usize = files.iter().map(|f| f.1.len() as usize).sum(); + + if size > MAX_SIZE { + let all = files.len(); + // keep ~75% of files (no floats required) + let to_keep : usize = (all >> 1) + (all >> 2); + let to_delete : usize = all - to_keep; + + println!("{} is {} bytes (MAX = {})", &Path::new(&dir).display(), size, MAX_SIZE); + println!("to keep: {}, to delete: {}", to_keep, to_delete); + + let really_delete = std::env::var("REALLY_DELETE").ok(); + + if let None = really_delete { + println!("dry-running. If you want to actually delete files, set REALLY_DELETE"); + } + + // sort oldest files to the front + files.sort_by_cached_key(|f| f.1.modified().ok()); + + for f in files.iter().take(to_delete) { + match really_delete { + None => { + println!("Would delete: {}", f.0.display()); + }, + Some(_) => { + println!("Deleting: {}", f.0.display()); + if let Err(e) = fs::remove_file(&f.0) { + println!("Warning: could not remove {}: {:?}", f.0.display(), e); + } + } + } + } + + } + + Ok(()) + } + ''); + + +in { + inherit + lru-dir + ; +} -- cgit 1.4.1