Unified · Split
| @@ -19,7 +19,7 @@ struct Delta { · 18 unmodified lines | |||
| 19 | #[derive(Debug)] | 19 | #[derive(Debug)] |
| 20 | pub enum ResolvedBase { | 20 | pub enum ResolvedBase { |
| 21 | InPack(Entry), | 21 | InPack(Entry), |
| 22 | OutOfPack(Range<usize>), | 22 | OutOfPack { end: usize }, |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | impl Delta { | 25 | impl Delta { |
| @@ -171,7 +171,8 @@ impl File { · 145 unmodified lines | |||
| 171 | let mut chain = SmallVec::<[Delta; 5]>::default(); | 171 | let mut chain = SmallVec::<[Delta; 5]>::default(); |
| 172 | let mut instruction_buffer_size = 0usize; | 172 | let mut instruction_buffer_size = 0usize; |
| 173 | let mut cursor = last.clone(); | 173 | let mut cursor = last.clone(); |
| 174 | let mut first_base_buffer_range: Option<Range<usize>> = None; | 174 | let mut base_buffer_end: Option<usize> = None; |
| 175 | // Find the first full base, either an undeltified object in the pack or a reference to another object. | ||
| 175 | while cursor.header.is_delta() { | 176 | while cursor.header.is_delta() { |
| 176 | let end = instruction_buffer_size | 177 | let end = instruction_buffer_size |
| 177 | .checked_add(cursor.size as usize) | 178 | .checked_add(cursor.size as usize) |
| @@ -190,8 +191,8 @@ impl File { · 12 unmodified lines | |||
| 190 | Header::OfsDelta { pack_offset } => self.entry(pack_offset), | 191 | Header::OfsDelta { pack_offset } => self.entry(pack_offset), |
| 191 | Header::RefDelta { oid } => match resolve(&oid, out) { | 192 | Header::RefDelta { oid } => match resolve(&oid, out) { |
| 192 | ResolvedBase::InPack(entry) => entry, | 193 | ResolvedBase::InPack(entry) => entry, |
| 193 | ResolvedBase::OutOfPack(range) => { | 194 | ResolvedBase::OutOfPack { end } => { |
| 194 | first_base_buffer_range = Some(range); | 195 | base_buffer_end = Some(end); |
| 195 | break; | 196 | break; |
| 196 | } | 197 | } |
| 197 | }, | 198 | }, |
| @@ -200,7 +201,7 @@ impl File { · 2 unmodified lines | |||
| 200 | } | 201 | } |
| 201 | let (first_buffer_end, second_buffer_end) = { | 202 | let (first_buffer_end, second_buffer_end) = { |
| 202 | let delta_instructions_size: u64 = chain.iter().map(|d| d.size() as u64).sum(); | 203 | let delta_instructions_size: u64 = chain.iter().map(|d| d.size() as u64).sum(); |
| 203 | let base_buffer_end = match first_base_buffer_range { | 204 | let base_buffer_end = match base_buffer_end { |
| 204 | None => { | 205 | None => { |
| 205 | let base_entry = cursor; | 206 | let base_entry = cursor; |
| 206 | out.resize( | 207 | out.resize( |
| @@ -215,19 +216,15 @@ impl File { · 8 unmodified lines | |||
| 215 | .try_into() | 216 | .try_into() |
| 216 | .expect("usize big enough for single entry base object size") | 217 | .expect("usize big enough for single entry base object size") |
| 217 | } | 218 | } |
| 218 | Some(range) => { | 219 | Some(end) => { |
| 219 | assert_eq!( | ||
| 220 | range.start, 0, | ||
| 221 | "We really expect to not start somewhere in the middle of a buffer" | ||
| 222 | ); | ||
| 223 | out.resize( | 220 | out.resize( |
| 224 | ((range.end - range.start) as u64 * 2 // * 2 for worst-case guess | 221 | (end as u64 * 2 // * 2 for worst-case guess |
| 225 | + delta_instructions_size) | 222 | + delta_instructions_size) |
| 226 | .try_into() | 223 | .try_into() |
| 227 | .expect("usize to be big enough for all deltas"), | 224 | .expect("usize to be big enough for all deltas"), |
| 228 | 0, | 225 | 0, |
| 229 | ); | 226 | ); |
| 230 | range.end | 227 | end |
| 231 | } | 228 | } |
| 232 | }; | 229 | }; |
| 233 | (base_buffer_end, base_buffer_end + base_buffer_end) // works because we have two equally sized sequential regions | 230 | (base_buffer_end, base_buffer_end + base_buffer_end) // works because we have two equally sized sequential regions |