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.
--- 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<u8> {
- 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<u8> {