diff --git a/gix-commitgraph/src/file/access.rs b/gix-commitgraph/src/file/access.rs index df9f6eb1782..57c75ae569c 100644 --- a/gix-commitgraph/src/file/access.rs +++ b/gix-commitgraph/src/file/access.rs @@ -57,7 +57,7 @@ impl File { let start = self.base_graphs_list_offset.unwrap_or(0); let base_graphs_list = &self.data[start..][..self.hash_len * usize::from(self.base_graph_count)]; base_graphs_list - .chunks(self.hash_len) + .chunks_exact(self.hash_len) .map(gix_hash::oid::from_bytes_unchecked) } diff --git a/gix-commitgraph/src/file/init.rs b/gix-commitgraph/src/file/init.rs index df9ef369cda..51c2739501f 100644 --- a/gix-commitgraph/src/file/init.rs +++ b/gix-commitgraph/src/file/init.rs @@ -259,8 +259,10 @@ impl TryFrom<&Path> for File { // Copied from gix-odb/pack/index/init.rs fn read_fan(d: &[u8]) -> ([u32; FAN_LEN], usize) { + assert!(d.len() >= FAN_LEN * 4); + let mut fan = [0; FAN_LEN]; - for (c, f) in d.chunks(4).zip(fan.iter_mut()) { + for (c, f) in d.chunks_exact(4).zip(fan.iter_mut()) { *f = u32::from_be_bytes(c.try_into().unwrap()); } (fan, FAN_LEN * 4) diff --git a/gix-index/src/decode/mod.rs b/gix-index/src/decode/mod.rs index f6bb126c4ee..801b319f7e7 100644 --- a/gix-index/src/decode/mod.rs +++ b/gix-index/src/decode/mod.rs @@ -96,9 +96,10 @@ impl State { let entries_res = match index_offsets_table { Some(entry_offsets) => { let chunk_size = (entry_offsets.len() as f32 / num_threads as f32).ceil() as usize; - let num_chunks = entry_offsets.chunks(chunk_size).count(); + let entry_offsets_chunked = entry_offsets.chunks(chunk_size); + let num_chunks = entry_offsets_chunked.len(); let mut threads = Vec::with_capacity(num_chunks); - for (id, chunks) in entry_offsets.chunks(chunk_size).enumerate() { + for (id, chunks) in entry_offsets_chunked.enumerate() { let chunks = chunks.to_vec(); threads.push( gix_features::parallel::build_thread() diff --git a/gix-pack/src/index/access.rs b/gix-pack/src/index/access.rs index 618e5dcb396..52523692aeb 100644 --- a/gix-pack/src/index/access.rs +++ b/gix-pack/src/index/access.rs @@ -31,7 +31,7 @@ impl index::File { fn iter_v1(&self) -> impl Iterator + '_ { match self.version { index::Version::V1 => self.data[V1_HEADER_SIZE..] - .chunks(N32_SIZE + self.hash_len) + .chunks_exact(N32_SIZE + self.hash_len) .take(self.num_objects as usize) .map(|c| { let (ofs, oid) = c.split_at(N32_SIZE); @@ -47,14 +47,19 @@ impl index::File { fn iter_v2(&self) -> impl Iterator + '_ { let pack64_offset = self.offset_pack_offset64_v2(); + let oids = self.data[V2_HEADER_SIZE..] + .chunks_exact(self.hash_len) + .take(self.num_objects as usize); + let crcs = self.data[self.offset_crc32_v2()..] + .chunks_exact(N32_SIZE) + .take(self.num_objects as usize); + let offsets = self.data[self.offset_pack_offset_v2()..] + .chunks_exact(N32_SIZE) + .take(self.num_objects as usize); + assert_eq!(oids.len(), crcs.len()); + assert_eq!(crcs.len(), offsets.len()); match self.version { - index::Version::V2 => izip!( - self.data[V2_HEADER_SIZE..].chunks(self.hash_len), - self.data[self.offset_crc32_v2()..].chunks(N32_SIZE), - self.data[self.offset_pack_offset_v2()..].chunks(N32_SIZE) - ) - .take(self.num_objects as usize) - .map(move |(oid, crc32, ofs32)| Entry { + index::Version::V2 => izip!(oids, crcs, offsets).map(move |(oid, crc32, ofs32)| Entry { oid: gix_hash::ObjectId::from_bytes_or_panic(oid), pack_offset: self.pack_offset_from_offset_v2(ofs32, pack64_offset), crc32: Some(crate::read_u32(crc32)), @@ -162,10 +167,10 @@ impl index::File { index::Version::V1 => self.iter().map(|e| e.pack_offset).collect(), index::Version::V2 => { let offset32_start = &self.data[self.offset_pack_offset_v2()..]; + let offsets32 = offset32_start.chunks_exact(N32_SIZE).take(self.num_objects as usize); + assert_eq!(self.num_objects as usize, offsets32.len()); let pack_offset_64_start = self.offset_pack_offset64_v2(); - offset32_start - .chunks(N32_SIZE) - .take(self.num_objects as usize) + offsets32 .map(|offset| self.pack_offset_from_offset_v2(offset, pack_offset_64_start)) .collect() } diff --git a/gix-pack/src/index/init.rs b/gix-pack/src/index/init.rs index 13eecdbdaad..180c0f8a3c8 100644 --- a/gix-pack/src/index/init.rs +++ b/gix-pack/src/index/init.rs @@ -83,8 +83,10 @@ impl index::File { } fn read_fan(d: &[u8]) -> ([u32; FAN_LEN], usize) { + assert!(d.len() >= FAN_LEN * N32_SIZE); + let mut fan = [0; FAN_LEN]; - for (c, f) in d.chunks(N32_SIZE).zip(fan.iter_mut()) { + for (c, f) in d.chunks_exact(N32_SIZE).zip(fan.iter_mut()) { *f = crate::read_u32(c); } (fan, FAN_LEN * N32_SIZE) diff --git a/gix-pack/src/index/traverse/with_lookup.rs b/gix-pack/src/index/traverse/with_lookup.rs index 9f1db3d0510..d0bc0e0566e 100644 --- a/gix-pack/src/index/traverse/with_lookup.rs +++ b/gix-pack/src/index/traverse/with_lookup.rs @@ -121,7 +121,7 @@ impl index::File { let (chunk_size, thread_limit, available_cores) = parallel::optimize_chunk_size_and_thread_limit(1000, Some(index_entries.len()), thread_limit, None); let there_are_enough_entries_to_process = || index_entries.len() > chunk_size * available_cores; - let input_chunks = index_entries.chunks(chunk_size.max(chunk_size)); + let input_chunks = index_entries.chunks(chunk_size); let reduce_progress = OwnShared::new(Mutable::new({ let mut p = progress.add_child_with_id("Traversing".into(), ProgressId::DecodedObjects.into()); p.init(Some(self.num_objects() as usize), progress::count("objects")); diff --git a/gix-pack/src/multi_index/chunk.rs b/gix-pack/src/multi_index/chunk.rs index 86e43714dba..e9a9aac9cdb 100644 --- a/gix-pack/src/multi_index/chunk.rs +++ b/gix-pack/src/multi_index/chunk.rs @@ -121,7 +121,7 @@ pub mod fanout { return None; } let mut out = [0; 256]; - for (c, f) in chunk.chunks(4).zip(out.iter_mut()) { + for (c, f) in chunk.chunks_exact(4).zip(out.iter_mut()) { *f = u32::from_be_bytes(c.try_into().unwrap()); } out.into() diff --git a/src/plumbing/main.rs b/src/plumbing/main.rs index c63340e407d..f7d93648abd 100644 --- a/src/plumbing/main.rs +++ b/src/plumbing/main.rs @@ -226,8 +226,8 @@ pub fn main() -> Result<()> { add_paths: add_path, prefix, files: add_virtual_file - .chunks(2) - .map(|c| (c[0].to_owned(), c[1].clone())) + .chunks_exact(2) + .map(|c| (c[0].clone(), c[1].clone())) .collect(), format: format.map(|f| match f { crate::plumbing::options::archive::Format::Internal => {