| @@ -43,12 +43,19 @@ where · 42 unmodified lines |
| 43 | 43 | |
| 44 | 44 | /// positive `change` values mean an object grew or was more commonly, was inserted. Negative values |
| 45 | 45 | /// mean the object shrunk, usually because there header changed from ref-deltas to ofs deltas. |
| 46 | | − fn track_change(&mut self, pack_offset: u64, change: i64, oid: impl Into<Option<ObjectId>>) { |
| 46 | + fn track_change( |
| 47 | + &mut self, |
| 48 | + shifted_pack_offset: u64, |
| 49 | + pack_offset: u64, |
| 50 | + change: i64, |
| 51 | + oid: impl Into<Option<ObjectId>>, |
| 52 | + ) { |
| 47 | 53 | if change == 0 { |
| 48 | 54 | return; |
| 49 | 55 | } |
| 50 | 56 | self.inserted_entry_length_at_offset.push(Change { |
| 51 | | − at_pack_offset: pack_offset, |
| 57 | + shifted_pack_offset, |
| 58 | + pack_offset, |
| 52 | 59 | _change_in_bytes: change, |
| 53 | 60 | oid: oid.into().unwrap_or_else(ObjectId::null_sha1), |
| 54 | 61 | }); |
| @@ -56,13 +63,14 @@ where · 1 unmodified line |
| 56 | 63 | } |
| 57 | 64 | |
| 58 | 65 | fn shift_entry_and_point_to_base_by_offset(&mut self, entry: &mut input::Entry, base_distance: u64) { |
| 59 | | − entry.pack_offset = self.shift_pack_offset(entry.pack_offset); |
| 66 | + let pack_offset = entry.pack_offset; |
| 67 | + entry.pack_offset = self.shift_pack_offset(pack_offset); |
| 60 | 68 | entry.header = Header::OfsDelta { base_distance }; |
| 61 | 69 | let previous_header_size = entry.header_size; |
| 62 | 70 | entry.header_size = entry.header.size(entry.decompressed_size) as u16; |
| 63 | 71 | |
| 64 | 72 | let change = entry.header_size as i64 - previous_header_size as i64; |
| 65 | | − self.track_change(entry.pack_offset, change, None); |
| 73 | + self.track_change(entry.pack_offset, pack_offset, change, None); |
| 66 | 74 | } |
| 67 | 75 | } |
| 68 | 76 | |
| @@ -93,7 +101,12 @@ where · 24 unmodified lines |
| 93 | 101 | Ok(e) => e, |
| 94 | 102 | }; |
| 95 | 103 | entry.pack_offset = self.shift_pack_offset(current_pack_offset); |
| 96 | | − self.track_change(entry.pack_offset, entry.bytes_in_pack() as i64, base_id); |
| 104 | + self.track_change( |
| 105 | + entry.pack_offset, |
| 106 | + current_pack_offset, |
| 107 | + entry.bytes_in_pack() as i64, |
| 108 | + base_id, |
| 109 | + ); |
| 97 | 110 | entry |
| 98 | 111 | } |
| 99 | 112 | None => { |
| @@ -109,7 +122,8 @@ where · 9 unmodified lines |
| 109 | 122 | Some(Ok(base_entry)) |
| 110 | 123 | } |
| 111 | 124 | Some(base_entry) => { |
| 112 | | − let base_distance = self.shift_pack_offset(entry.pack_offset) - base_entry.at_pack_offset; |
| 125 | + let base_distance = |
| 126 | + self.shift_pack_offset(entry.pack_offset) - base_entry.shifted_pack_offset; |
| 113 | 127 | self.shift_entry_and_point_to_base_by_offset(&mut entry, base_distance); |
| 114 | 128 | Some(Ok(entry)) |
| 115 | 129 | } |
| @@ -117,10 +131,27 @@ where · 1 unmodified line |
| 117 | 131 | } |
| 118 | 132 | _ => { |
| 119 | 133 | if self.inserted_entries_length_in_bytes != 0 { |
| 120 | | − entry.pack_offset = self.shift_pack_offset(entry.pack_offset); |
| 121 | | − if let Header::OfsDelta { base_distance: _ } = entry.header { |
| 122 | | − // self.inserted_entry_length_at_offset.partition_point() |
| 123 | | − // todo!("add all objects that have been added since to the delta offset, compute new size and adjust") |
| 134 | + if let Header::OfsDelta { base_distance } = entry.header { |
| 135 | + let base_pack_offset = entry |
| 136 | + .pack_offset |
| 137 | + .checked_sub(base_distance) |
| 138 | + .expect("distance to be in range of pack"); |
| 139 | + entry.pack_offset = self.shift_pack_offset(entry.pack_offset); |
| 140 | + dbg!(base_pack_offset, entry.pack_offset); |
| 141 | + match self |
| 142 | + .inserted_entry_length_at_offset |
| 143 | + .binary_search_by_key(&base_pack_offset, |c| c.pack_offset) |
| 144 | + { |
| 145 | + Ok(index) => { |
| 146 | + dbg!(index, &self.inserted_entry_length_at_offset[index..]); |
| 147 | + todo!("we point exactly at an entry that changed, but this one might be inserted") |
| 148 | + } |
| 149 | + Err(_index) => { |
| 150 | + todo!("close, aggregate the size changes since then to know where we are pointing") |
| 151 | + } |
| 152 | + } |
| 153 | + } else { |
| 154 | + entry.pack_offset = self.shift_pack_offset(entry.pack_offset); |
| 124 | 155 | } |
| 125 | 156 | } |
| 126 | 157 | Some(Ok(entry)) |
| @@ -137,7 +168,8 @@ where · 10 unmodified lines |
| 137 | 168 | |
| 138 | 169 | #[derive(Debug)] |
| 139 | 170 | struct Change { |
| 140 | | − at_pack_offset: u64, |
| 171 | + pack_offset: u64, |
| 172 | + shifted_pack_offset: u64, |
| 141 | 173 | _change_in_bytes: i64, |
| 142 | 174 | oid: ObjectId, |
| 143 | 175 | } |