From 985567fb45892cd6b139d6671bddcec2cb24df56 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Sat, 29 Dec 2018 17:26:32 +0100 Subject: [PATCH] src/catar/encoder.rs: cleanup, factor out write_goodbye_table --- src/catar/encoder.rs | 86 +++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/src/catar/encoder.rs b/src/catar/encoder.rs index 5306f767..ed2ca6bb 100644 --- a/src/catar/encoder.rs +++ b/src/catar/encoder.rs @@ -115,6 +115,42 @@ impl CaTarEncoder { Ok(()) } + fn write_goodbye_table(&mut self, goodbye_offset: usize, goodbye_items: &[CaFormatGoodbyeItem]) -> Result<(), Error> { + + let item_count = goodbye_items.len(); + + let goodbye_table_size = (item_count + 1)*std::mem::size_of::(); + + self.write_header(CA_FORMAT_GOODBYE, goodbye_table_size as u64)?; + + if goodbye_table_size > FILE_COPY_BUFFER_SIZE { + bail!("goodby table too large ({} > {})", goodbye_table_size, FILE_COPY_BUFFER_SIZE); + } + + let buffer = &mut self.file_copy_buffer; + let buffer_ptr = buffer.as_ptr(); + + copy_binary_search_tree(item_count, |s, d| { + let item = &goodbye_items[s]; + let offset = d*std::mem::size_of::(); + let dest = crate::tools::map_struct_mut::(&mut buffer[offset..]).unwrap(); + dest.offset = u64::to_le(item.offset); + dest.size = u64::to_le(item.size); + dest.hash = u64::to_le(item.hash); + }); + + // append CaFormatGoodbyeTail as last item + let offset = item_count*std::mem::size_of::(); + let dest = crate::tools::map_struct_mut::(&mut buffer[offset..]).unwrap(); + dest.offset = u64::to_le(goodbye_offset as u64); + dest.size = u64::to_le((goodbye_table_size + std::mem::size_of::()) as u64); + dest.hash = u64::to_le(CA_FORMAT_GOODBYE_TAIL_MARKER); + + self.flush_copy_buffer(goodbye_table_size)?; + + Ok(()) + } + fn encode_dir(&mut self, dir: &mut nix::dir::Dir) -> Result<(), Error> { println!("encode_dir: {:?} start {}", self.current_path, self.writer_pos); @@ -159,7 +195,7 @@ impl CaTarEncoder { name_list.sort_unstable_by(|a, b| a.0.cmp(&b.0)); - let mut goodby_items = vec![]; + let mut goodbye_items = vec![]; for (filename, stat) in &name_list { self.current_path.push(std::ffi::OsStr::from_bytes(filename.as_bytes())); @@ -207,10 +243,10 @@ impl CaTarEncoder { let end_pos = self.writer_pos; - goodby_items.push(CaFormatGoodbyeItem { + goodbye_items.push(CaFormatGoodbyeItem { offset: start_pos as u64, size: (end_pos - start_pos) as u64, - hash: compute_goodby_hash(&filename), + hash: compute_goodbye_hash(&filename), }); self.current_path.pop(); @@ -218,45 +254,15 @@ impl CaTarEncoder { println!("encode_dir: {:?} end {}", self.current_path, self.writer_pos); - let goodby_start = self.writer_pos as u64; - - let item_count = goodby_items.len(); - let goodby_table_size = (item_count + 1)*std::mem::size_of::(); - - for item in &mut goodby_items { - item.offset = goodby_start - item.offset; + // fixup goodby item offsets + let goodbye_start = self.writer_pos as u64; + for item in &mut goodbye_items { + item.offset = goodbye_start - item.offset; } - // fixme: sort goodby_items (BST) + let goodbye_offset = self.writer_pos - dir_start_pos; - let goodby_offset = self.writer_pos - dir_start_pos; - - self.write_header(CA_FORMAT_GOODBYE, goodby_table_size as u64)?; - - if goodby_table_size > FILE_COPY_BUFFER_SIZE { - bail!("goodby table too large ({} > {})", goodby_table_size, FILE_COPY_BUFFER_SIZE); - } - - let buffer = &mut self.file_copy_buffer; - let buffer_ptr = buffer.as_ptr(); - - copy_binary_search_tree(item_count, |s, d| { - let item = &goodby_items[s]; - let offset = d*std::mem::size_of::(); - let dest = crate::tools::map_struct_mut::(&mut buffer[offset..]).unwrap(); - dest.offset = u64::to_le(item.offset); - dest.size = u64::to_le(item.size); - dest.hash = u64::to_le(item.hash); - }); - - // append CaFormatGoodbyeTail as last item - let offset = item_count*std::mem::size_of::(); - let dest = crate::tools::map_struct_mut::(&mut buffer[offset..]).unwrap(); - dest.offset = u64::to_le(goodby_offset as u64); - dest.size = u64::to_le((goodby_table_size + std::mem::size_of::()) as u64); - dest.hash = u64::to_le(CA_FORMAT_GOODBYE_TAIL_MARKER); - - self.flush_copy_buffer(goodby_table_size)?; + self.write_goodbye_table(goodbye_offset, &goodbye_items)?; println!("encode_dir: {:?} end1 {}", self.current_path, self.writer_pos); Ok(()) @@ -334,7 +340,7 @@ impl CaTarEncoder { } } -fn compute_goodby_hash(name: &CStr) -> u64 { +fn compute_goodbye_hash(name: &CStr) -> u64 { use std::hash::Hasher; let mut hasher = SipHasher24::new_with_keys(0x8574442b0f1d84b3, 0x2736ed30d1c22ec1);