History

first version of delta-apply, with a fatal flaw :D

It's interesting how low-level operations on bytes can be a bit troublesome in purely safe and potentially high-level Rust with iterators. Git, anyway, really wants free access to memory in this case!

Sebastian Thiel committed 6 years ago

Commit f38ec001 parent a9000081 file · +44 −3Browse files

Unified · Split

gitoxide-odb/src/pack/file/mod.rs+44−3
@@ -248,7 +248,6 @@ impl File { · 247 unmodified lines
248 let (result_size, consumed) = delta_header_size(&buf[consumed..]);248 let (result_size, consumed) = delta_header_size(&buf[consumed..]);
249 delta.header_size += consumed;249 delta.header_size += consumed;
250 delta.result_size = result_size;250 delta.result_size = result_size;
251 dbg!(delta);
252 }251 }
253 252
254 // From oldest to most recent, apply all deltas, swapping the buffer back and forth253 // From oldest to most recent, apply all deltas, swapping the buffer back and forth
@@ -285,8 +284,50 @@ impl File { · 30 unmodified lines
285 }284 }
286}285}
287 286
288fn apply_delta(source: &[u8], target: &mut [u8], instructions: &[u8]) {287fn apply_delta(mut base: &[u8], mut target: &mut [u8], instructions: &[u8]) {
289 unimplemented!("delta application")288 let mut iter = instructions.into_iter();
289 while let Some(cmd) = iter.next() {
290 match cmd {
291 cmd if cmd & 0b1000_0000 != 0 => {
292 let (mut ofs, mut size): (u32, u32) = (0, 0);
293 if cmd & 0b0000_0001 != 0 {
294 ofs = *iter.next().unwrap() as u32;
295 }
296 if cmd & 0b0000_0010 != 0 {
297 ofs |= (*iter.next().unwrap() as u32) << 8;
298 }
299 if cmd & 0b0000_0100 != 0 {
300 ofs |= (*iter.next().unwrap() as u32) << 16;
301 }
302 if cmd & 0b0000_1000 != 0 {
303 ofs |= (*iter.next().unwrap() as u32) << 24;
304 }
305 if cmd & 0b0001_0000 != 0 {
306 size = *iter.next().unwrap() as u32;
307 }
308 if cmd & 0b0010_0000 != 0 {
309 size |= (*iter.next().unwrap() as u32) << 8;
310 }
311 if cmd & 0b0100_0000 != 0 {
312 size |= (*iter.next().unwrap() as u32) << 16;
313 }
314 if size == 0 {
315 size = 0x10000; // 65536
316 }
317 let ofs = ofs as usize;
318 std::io::Write::write(&mut target, &base[ofs..ofs + size as usize])
319 .expect("delta copy from base: byte slices must match");
320 }
321 0 => panic!("encounted unsupported command code: 0"),
322 size => {
323 // Fixme: must copy from instruction buffer!
324 let (dest, rest) = base.split_at(*size as usize);
325 std::io::Write::write(&mut target, dest)
326 .expect("delta copy data: slice sizes to match up");
327 base = rest;
328 }
329 }
330 }
290}331}
291 332
292fn delta_header_size(d: &[u8]) -> (u64, usize) {333fn delta_header_size(d: &[u8]) -> (u64, usize) {