This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knot2 / crates / knot-maintenance / src / bitmap.rs
2.3 kB 71 lines
1use std::path::Path; 2 3use knot_git::Repo; 4 5use crate::MaintError; 6use crate::fsio::{self, MIDX_SIDECAR_PREFIX, PackStem}; 7 8pub fn exists(objects_dir: &Path) -> bool { 9 fsio::pack_idx_paths(objects_dir) 10 .iter() 11 .any(|idx| idx.with_extension("bitmap").exists()) 12} 13 14pub fn refresh(repo: &Repo, objects_dir: &Path) -> Result<bool, MaintError> { 15 let idxs = fsio::pack_idx_paths(objects_dir); 16 match idxs.as_slice() { 17 [only] => { 18 let wrote = knot_git::write_bitmap(repo, only) 19 .map_err(|error| MaintError::Pack(error.to_string()))?; 20 let stem = PackStem::of(only); 21 prune_sidecars(objects_dir, stem.as_ref()); 22 Ok(wrote) 23 } 24 [] => { 25 prune_sidecars(objects_dir, None); 26 Ok(false) 27 } 28 _ => { 29 let wrote = knot_git::write_midx_bitmap(repo) 30 .map_err(|error| MaintError::Pack(error.to_string()))?; 31 let keep = current_midx_stem(objects_dir); 32 prune_sidecars(objects_dir, keep.as_ref()); 33 Ok(wrote) 34 } 35 } 36} 37 38fn current_midx_stem(objects_dir: &Path) -> Option<PackStem> { 39 let path = objects_dir.join("pack").join("multi-pack-index"); 40 let file = 41 gix_pack::multi_index::File::at(path, Some(crate::midx::MIDX_ALLOC_LIMIT_BYTES)).ok()?; 42 Some(PackStem::midx_sidecar( 43 &file.checksum().to_hex().to_string(), 44 )) 45} 46 47fn prune_sidecars(objects_dir: &Path, keep_stem: Option<&PackStem>) { 48 let pack_dir = objects_dir.join("pack"); 49 let Ok(entries) = std::fs::read_dir(&pack_dir) else { 50 return; 51 }; 52 entries 53 .filter_map(Result::ok) 54 .map(|entry| entry.path()) 55 .filter(|path| is_bitmap_sidecar(path)) 56 .filter(|path| PackStem::of(path).as_ref() != keep_stem) 57 .for_each(|path| { 58 let _ = std::fs::remove_file(path); 59 }); 60} 61 62fn is_bitmap_sidecar(path: &Path) -> bool { 63 match path.extension().and_then(|ext| ext.to_str()) { 64 Some("bitmap") => true, 65 Some("rev") => path 66 .file_name() 67 .and_then(|name| name.to_str()) 68 .is_some_and(|name| name.starts_with(MIDX_SIDECAR_PREFIX)), 69 _ => false, 70 } 71}