This repository has no description
0

Configure Feed

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

core / knot2 / third_party / gix-pack / src / lib.rs
3.4 kB 121 lines
1//! Git stores all of its data as _Objects_, which are data along with a hash over all data. Storing objects efficiently 2//! is what git packs are concerned about. 3//! 4//! Packs consist of [data files][data::File] and [index files][index::File]. The latter can be generated from a data file 5//! and make accessing objects within a pack feasible. 6//! 7//! A [Bundle] conveniently combines a data pack alongside its index to allow [finding][Find] objects or verifying the pack. 8//! Objects returned by `.find(…)` are [objects][gix_object::Data] which know their pack location in order to speed up 9//! various common operations like creating new packs from existing ones. 10//! 11//! When traversing all objects in a pack, a _delta tree acceleration structure_ can be built from pack data or an index 12//! in order to decompress packs in parallel and without any waste. 13//! ## Feature Flags 14#![cfg_attr( 15 all(doc, feature = "document-features"), 16 doc = ::document_features::document_features!() 17)] 18#![cfg_attr(all(doc, feature = "document-features"), feature(doc_cfg))] 19#![deny(unsafe_code)] 20 21use std::{borrow::Cow, ops::Deref, path::Path}; 22 23/// The default in-memory backing store for index and multi-index files. 24#[allow(missing_docs)] 25pub struct MMap(Vec<u8>); 26 27impl MMap { 28 #[allow(missing_docs)] 29 pub fn map(file: &std::fs::File) -> std::io::Result<Self> { 30 use std::os::unix::fs::FileExt; 31 let len = usize::try_from(file.metadata()?.len()) 32 .map_err(|_| std::io::Error::other("file too large to load into memory"))?; 33 let mut bytes = vec![0u8; len]; 34 file.read_exact_at(&mut bytes, 0)?; 35 Ok(MMap(bytes)) 36 } 37} 38 39impl Deref for MMap { 40 type Target = [u8]; 41 42 fn deref(&self) -> &[u8] { 43 &self.0 44 } 45} 46 47/// A byte-oriented backing store for pack data and indices. 48pub trait FileData: Deref<Target = [u8]> {} 49 50impl<T> FileData for T where T: Deref<Target = [u8]> {} 51 52/// 53pub mod bundle; 54/// A bundle of pack data and the corresponding pack index 55pub struct Bundle { 56 /// The pack file corresponding to `index` 57 pub pack: data::File, 58 /// The index file corresponding to `pack` 59 pub index: index::File, 60} 61 62/// 63pub mod find; 64 65/// 66pub mod cache; 67/// 68pub mod data; 69 70mod find_traits; 71pub use find_traits::{Find, FindExt}; 72 73/// 74pub mod index; 75/// 76pub mod multi_index; 77 78/// 79pub mod verify; 80 81mod mmap { 82 use std::path::Path; 83 84 pub fn read_only(path: &Path) -> std::io::Result<super::MMap> { 85 Ok(super::MMap(std::fs::read(path)?)) 86 } 87} 88 89/// Return a display-friendly name for pack- or index-related progress messages. 90/// 91/// Prefer the file name, but fall back to the full path for paths without a terminal component. 92fn source_name(path: &Path) -> Cow<'_, str> { 93 if path.as_os_str().is_empty() { 94 Cow::Borrowed("<memory>") 95 } else if let Some(name) = path.file_name() { 96 name.to_string_lossy() 97 } else { 98 path.as_os_str().to_string_lossy() 99 } 100} 101 102#[inline] 103fn read_u32(b: &[u8]) -> u32 { 104 u32::from_be_bytes(b.try_into().unwrap()) 105} 106 107#[inline] 108fn read_u64(b: &[u8]) -> u64 { 109 u64::from_be_bytes(b.try_into().unwrap()) 110} 111 112fn exact_vec<T>(capacity: usize) -> Vec<T> { 113 let mut v = Vec::new(); 114 v.reserve_exact(capacity); 115 v 116} 117 118#[inline] 119fn fan_is_monotonically_increasing(fan: &[u32]) -> bool { 120 !fan.windows(2).any(|window| window[0] > window[1]) 121}