Skip to content

Instantly share code, notes, and snippets.

@Horusiath
Created June 26, 2024 19:10
Show Gist options
  • Save Horusiath/534360134b35e79748b29742aa1e2382 to your computer and use it in GitHub Desktop.
Save Horusiath/534360134b35e79748b29742aa1e2382 to your computer and use it in GitHub Desktop.
varint encoding and length-prefix int encoding
#[inline]
fn zigzag_encode(from: i64) -> u64 {
((from << 1) ^ (from >> 63)) as u64
}
// see: http://stackoverflow.com/a/2211086/56332
// casting required because operations like unary negation
// cannot be performed on unsigned integers
#[inline]
fn zigzag_decode(from: u64) -> i64 {
((from >> 1) ^ (-((from & 1) as i64)) as u64) as i64
}
const CONTINUATION_FLAG: u8 = 0b1000_0000;
const MASK: u8 = 0 ^ CONTINUATION_FLAG;
fn varint_encode(mut n: u64, buf: &mut [u8]) -> usize {
let mut i = 0;
while n >= CONTINUATION_FLAG as u64 {
// n won't fit in 7 bits, take the lowest 7 bits of n
// and set the continuation bit
buf[i] = MASK | (n as u8);
n >>= 7;
i += 1;
}
// put remaining bits in the last byte
buf[i] = n as u8;
i + 1
}
fn varint_decode(bytes: &[u8]) -> Option<(u64, usize)> {
let mut result: u64 = 0;
// varint from u64 will never take more than 10 bytes
for i in 0..bytes.len().min(10) {
let byte = bytes[i];
// clear the continuation bit and shift byte by 7 bits * its position
result |= ((byte & MASK) as u64) << (i * 7);
if byte & CONTINUATION_FLAG == 0 {
// continuation bit not set, finished decoding
return Some((result, i));
}
}
None // never to stop byte
}
fn prefix_encode(mut n: u64, buf: &mut [u8]) -> usize {
let mut i = 0;
let mut j = 1;
while i < 8 {
let byte = (n >> 8 * (7 - i)) as u8;
if byte != 0 {
buf[j] = byte;
j += 1;
}
}
buf[0] = (j - 1) as u8;
j
}
fn prefix_decode(bytes: &[u8]) -> Option<(u64, usize)> {
let len = bytes[0] as usize;
if len > bytes.len() || len > 9 {
return None;
}
let mut result = [0; 8];
result.copy_from_slice(&bytes[1..=len]);
Some((u64::from_be_bytes(result), len))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment