# HG changeset patch # User Arseniy Alekseyev # Date 1676572866 0 # Node ID 5ce53ff6133a9f7fea3e2bd3d9368c35a19c7350 # Parent 96d31efd21f7908e977aab39d458b1c9a87ba921 rhg: in path_encode add a DestArr type This is an implementation of Sink trait that writes into a fixed-size buffer on the stack, so identical to what was done before, but it makes the code of [hash_encode] easier to understand by dropping all these slice manipulations. diff -r 96d31efd21f7 -r 5ce53ff6133a rust/hg-core/src/revlog/path_encode.rs --- a/rust/hg-core/src/revlog/path_encode.rs Thu Feb 16 18:29:52 2023 +0000 +++ b/rust/hg-core/src/revlog/path_encode.rs Thu Feb 16 18:41:06 2023 +0000 @@ -45,6 +45,38 @@ bitset[(c as usize) >> 5] & (1 << (c & 31)) != 0 } +const MAXENCODE: usize = 4096 * 4; + +struct DestArr { + buf: [u8; MAXENCODE], + pub len: usize, +} + +impl DestArr { + pub fn create() -> Self { + DestArr { + buf: [0; MAXENCODE], + len: 0, + } + } + + pub fn contents(&self) -> &[u8] { + &self.buf[..self.len] + } +} + +impl Sink for DestArr { + fn write_byte(&mut self, c: u8) { + self.buf[self.len] = c; + self.len += 1; + } + + fn write_bytes(&mut self, src: &[u8]) { + self.buf[self.len..self.len + src.len()].copy_from_slice(src); + self.len += src.len(); + } +} + struct Dest<'a> { dest: Option<&'a mut [u8]>, pub len: usize, @@ -567,26 +599,19 @@ } } -const MAXENCODE: usize = 4096 * 4; fn hash_encode(src: &[u8]) -> Vec { - let dired = &mut [0; MAXENCODE]; - let mut dired_dest = Dest::create(dired); - let lowered = &mut [0; MAXENCODE]; - let mut lowered_dest = Dest::create(lowered); - let auxed = &mut [0; MAXENCODE]; - let mut auxed_dest = Dest::create(auxed); + let mut dired = DestArr::create(); + let mut lowered = DestArr::create(); + let mut auxed = DestArr::create(); let baselen = (src.len() - 5) * 3; if baselen >= MAXENCODE { panic!("path_encode::hash_encore: string too long: {}", baselen) }; - encode_dir(&mut dired_dest, src); - let dirlen = dired_dest.len; - let sha = Sha1::digest(&dired[..dirlen]); - lower_encode(&mut lowered_dest, &dired[..dirlen][5..]); - let lowerlen = lowered_dest.len; - aux_encode(&mut auxed_dest, &lowered[..lowerlen]); - let auxlen = auxed_dest.len; - hash_mangle(&auxed[..auxlen], &sha) + encode_dir(&mut dired, src); + let sha = Sha1::digest(dired.contents()); + lower_encode(&mut lowered, &dired.contents()[5..]); + aux_encode(&mut auxed, lowered.contents()); + hash_mangle(auxed.contents(), &sha) } pub fn path_encode(path: &[u8]) -> Vec {