From 17a93c3f072c4e3a9a28cf8b11e44e065232b293 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Fri, 31 Dec 2021 12:24:38 +0800 Subject: [PATCH] Writing of chunk index (#279) --- git-chunk/src/file/write.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/git-chunk/src/file/write.rs b/git-chunk/src/file/write.rs index d2e0eb8910d..81b3b69d277 100644 --- a/git-chunk/src/file/write.rs +++ b/git-chunk/src/file/write.rs @@ -87,20 +87,48 @@ impl Index { } /// Plan to write a new chunk as part of the index when [`write_to()`][Index::write_to()] is called. pub fn plan_chunk(&mut self, chunk: crate::Id, exact_size_on_disk: u64) { - self.will_write = true; + assert!(self.will_write, "BUG: create the index with `for_writing()`"); + assert!( + !self.chunks.iter().any(|e| e.kind == chunk), + "BUG: must not add chunk of same kind twice: {:?}", + std::str::from_utf8(&chunk) + ); self.chunks.push(Entry { kind: chunk, offset: 0..exact_size_on_disk, }) } + /// Return the amount of chunks we currently know. + pub fn num_chunks(&self) -> usize { + self.chunks.len() + } + /// After [planning all chunks][Index::plan_chunk()] call this method with the destination to write the chunks to. /// Use the [Chunk] writer to write each chunk in order. - pub fn into_write(self, out: W) -> std::io::Result> + /// `current_offset` is the byte position at which `out` will continue writing. + pub fn into_write(self, mut out: W, mut current_offset: usize) -> std::io::Result> where W: std::io::Write, { - // TODO: write index + assert!( + self.will_write, + "BUG: create the index with `for_writing()`, cannot write decoded indices" + ); + /// First chunk starts past the table of contents + let mut current_offset = (current_offset + Self::size_for_entries(self.num_chunks())) as u64; + + for entry in &self.chunks { + out.write_all(&entry.kind)?; + out.write_all(¤t_offset.to_be_bytes())?; + + current_offset += entry.offset.end; + } + + // sentinel to mark end of chunks + out.write_all(&0u32.to_be_bytes())?; + out.write_all(¤t_offset.to_be_bytes())?; + Ok(Chunk::new(out, self.chunks.into())) } }