…because • decompressed deltas are really not useful nor do they speed up anything. Oposedly, it costs more to allocate. * base objects at least are fully resolved so that might one day be useful.
Unified · Split
| @@ -35,8 +35,10 @@ pub struct Entry { · 34 unmodified lines | |||
| 35 | /// These do not contain the header, which makes it possible to easily replace a RefDelta with offset deltas | 35 | /// These do not contain the header, which makes it possible to easily replace a RefDelta with offset deltas |
| 36 | /// when resolving thin packs. | 36 | /// when resolving thin packs. |
| 37 | pub compressed: Vec<u8>, | 37 | pub compressed: Vec<u8>, |
| 38 | /// The decompressed data. | 38 | /// The decompressed data of a base object, which are the only ones who are fully resolved. |
| 39 | pub decompressed: Vec<u8>, | 39 | pub decompressed: Option<Vec<u8>>, |
| 40 | /// The amount of decompressed bytes | ||
| 41 | pub decompressed_size: u64, | ||
| 40 | /// Set for the last object in the iteration, providing the hash over all bytes of the iteration | 42 | /// Set for the last object in the iteration, providing the hash over all bytes of the iteration |
| 41 | /// for use as trailer in a pack | 43 | /// for use as trailer in a pack |
| 42 | pub trailer: Option<owned::Id>, | 44 | pub trailer: Option<owned::Id>, |
| @@ -142,8 +144,13 @@ where · 99 unmodified lines | |||
| 142 | decompressor, | 144 | decompressor, |
| 143 | }; | 145 | }; |
| 144 | 146 | ||
| 145 | let mut decompressed = Vec::with_capacity(entry.decompressed_size as usize); | 147 | let (bytes_copied, decompressed) = if entry.header.is_delta() { |
| 146 | let bytes_copied = io::copy(&mut reader, &mut decompressed)?; | 148 | let mut decompressed = Vec::with_capacity(entry.decompressed_size as usize); |
| 149 | let bytes_copied = io::copy(&mut reader, &mut decompressed)?; | ||
| 150 | (bytes_copied, Some(decompressed)) | ||
| 151 | } else { | ||
| 152 | (io::copy(&mut reader, &mut io::sink())?, None) | ||
| 153 | }; | ||
| 147 | debug_assert_eq!( | 154 | debug_assert_eq!( |
| 148 | bytes_copied, entry.decompressed_size, | 155 | bytes_copied, entry.decompressed_size, |
| 149 | "We should have decompressed {} bytes, but got {} instead", | 156 | "We should have decompressed {} bytes, but got {} instead", |
| @@ -201,6 +208,7 @@ where · 51 unmodified lines | |||
| 201 | compressed, | 208 | compressed, |
| 202 | pack_offset, | 209 | pack_offset, |
| 203 | decompressed, | 210 | decompressed, |
| 211 | decompressed_size: bytes_copied, | ||
| 204 | trailer, | 212 | trailer, |
| 205 | }) | 213 | }) |
| 206 | } | 214 | } |
| @@ -55,15 +55,16 @@ impl pack::index::File { · 54 unmodified lines | |||
| 55 | pack_offset, | 55 | pack_offset, |
| 56 | header_size, | 56 | header_size, |
| 57 | compressed, | 57 | compressed, |
| 58 | decompressed, | 58 | decompressed: _, |
| 59 | decompressed_size, | ||
| 59 | trailer, | 60 | trailer, |
| 60 | } = entry?; | 61 | } = entry?; |
| 61 | 62 | ||
| 62 | let compressed_len = compressed.len(); | 63 | let compressed_len = compressed.len(); |
| 63 | bytes_to_process += decompressed.len() as u64; | 64 | bytes_to_process += decompressed_size; |
| 64 | let entry_len = header_size as usize + compressed_len; | 65 | let entry_len = header_size as usize + compressed_len; |
| 65 | let crc32 = { | 66 | let crc32 = { |
| 66 | let header_len = header.to_write(decompressed.len() as u64, header_buf.as_mut())?; | 67 | let header_len = header.to_write(decompressed_size, header_buf.as_mut())?; |
| 67 | let state = hash::crc32_update(0, &header_buf[..header_len]); | 68 | let state = hash::crc32_update(0, &header_buf[..header_len]); |
| 68 | hash::crc32_update(state, &compressed) | 69 | hash::crc32_update(state, &compressed) |
| 69 | }; | 70 | }; |
| @@ -298,14 +298,21 @@ fn pack_lookup() -> Result<(), Box<dyn std::error::Error>> { · 297 unmodified lines | |||
| 298 | ); | 298 | ); |
| 299 | 299 | ||
| 300 | let mut buf = Vec::new(); | 300 | let mut buf = Vec::new(); |
| 301 | buf.resize(entry.decompressed.len(), 0); | 301 | buf.resize(entry.decompressed_size as usize, 0); |
| 302 | let pack_entry = pack.entry(offset_from_index); | 302 | let pack_entry = pack.entry(offset_from_index); |
| 303 | pack.decompress_entry(&pack_entry, &mut buf)?; | 303 | pack.decompress_entry(&pack_entry, &mut buf)?; |
| 304 | 304 | ||
| 305 | assert_eq!( | 305 | assert_eq!( |
| 306 | buf, entry.decompressed, | 306 | buf.len() as u64, |
| 307 | "the decompressed bytes are the same no matter what who decompressed them" | 307 | entry.decompressed_size, |
| 308 | "the decompressed length are the same no matter what decompressed them" | ||
| 308 | ); | 309 | ); |
| 310 | if let Some(decompressed) = entry.decompressed { | ||
| 311 | assert_eq!( | ||
| 312 | buf, decompressed, | ||
| 313 | "the decompressed bytes are the same no matter what decompressed them" | ||
| 314 | ); | ||
| 315 | } | ||
| 309 | 316 | ||
| 310 | let next_offset_index = sorted_offsets | 317 | let next_offset_index = sorted_offsets |
| 311 | .binary_search(&entry.pack_offset) | 318 | .binary_search(&entry.pack_offset) |
| @@ -4,7 +4,7 @@ use git_odb::pack; · 3 unmodified lines | |||
| 4 | fn size_of_entry() { | 4 | fn size_of_entry() { |
| 5 | assert_eq!( | 5 | assert_eq!( |
| 6 | std::mem::size_of::<pack::data::iter::Entry>(), | 6 | std::mem::size_of::<pack::data::iter::Entry>(), |
| 7 | 104, | 7 | 112, |
| 8 | "let's keep the size in check as we have many of them" | 8 | "let's keep the size in check as we have many of them" |
| 9 | ); | 9 | ); |
| 10 | } | 10 | } |
| @@ -22,7 +22,7 @@ mod new_from_header { · 11 unmodified lines | |||
| 22 | let entry = entry?; | 22 | let entry = entry?; |
| 23 | 23 | ||
| 24 | let mut buf = Vec::<u8>::new(); | 24 | let mut buf = Vec::<u8>::new(); |
| 25 | entry.header.to_write(entry.decompressed.len() as u64, &mut buf)?; | 25 | entry.header.to_write(entry.decompressed_size, &mut buf)?; |
| 26 | let new_entry = pack::data::Entry::from_bytes(&buf, entry.pack_offset); | 26 | let new_entry = pack::data::Entry::from_bytes(&buf, entry.pack_offset); |
| 27 | 27 | ||
| 28 | assert_eq!( | 28 | assert_eq!( |
| @@ -31,8 +31,7 @@ mod new_from_header { · 2 unmodified lines | |||
| 31 | "it should consume all provided bytes" | 31 | "it should consume all provided bytes" |
| 32 | ); | 32 | ); |
| 33 | assert_eq!( | 33 | assert_eq!( |
| 34 | new_entry.decompressed_size, | 34 | new_entry.decompressed_size, entry.decompressed_size as u64, |
| 35 | entry.decompressed.len() as u64, | ||
| 36 | "decoded size must match" | 35 | "decoded size must match" |
| 37 | ); | 36 | ); |
| 38 | assert_eq!(new_entry.header, entry.header, "headers match after roundtrip"); | 37 | assert_eq!(new_entry.header, entry.header, "headers match after roundtrip"); |