-
-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid 64-bit arithmetic in LEB encoding #345
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
pub(crate) fn leb64(x: u64, buf: &mut [u8; 10]) -> usize { | ||
/// LEB128-encodes a `usize` value into `buf`. | ||
/// | ||
/// This handles 32-bit and 64-bit `usize`. | ||
pub(crate) fn leb64(x: usize, buf: &mut [u8; 10]) -> usize { | ||
let mut low = x as u32; | ||
let mut high = (x >> 32) as u32; | ||
let mut high = ((x >> 16) >> 16) as u32; | ||
|
||
let mut i = 0; | ||
loop { | ||
|
@@ -58,8 +61,9 @@ pub(crate) fn leb64(x: u64, buf: &mut [u8; 10]) -> usize { | |
} | ||
} | ||
|
||
pub fn zigzag_encode(v: i64) -> u64 { | ||
((v << 1) ^ (v >> 63)) as u64 | ||
pub fn zigzag_encode(v: isize) -> usize { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: a 1 sentence doc on what's happening here for those could be helpful who are not familiar with zigzag encoding (not blocking though) |
||
const USIZE_BITS: usize = core::mem::size_of::<usize>() * 8; | ||
((v << 1) ^ (v >> (USIZE_BITS - 1))) as usize | ||
} | ||
|
||
#[cfg(test)] | ||
|
@@ -86,26 +90,28 @@ mod tests { | |
assert_eq!(buf[..i], [0x80, 1]); | ||
buf.iter_mut().for_each(|b| *b = 0x55); | ||
|
||
let i = leb64((1 << 32) - 1, &mut buf); | ||
assert_eq!(buf[..i], [0xff, 0xff, 0xff, 0xff, 0xf]); | ||
buf.iter_mut().for_each(|b| *b = 0x55); | ||
if cfg!(target_pointer_width = "64") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. another nitpick: it's not very intuitive to figure out what's being tested here... Personally I'd put each check in a dedicated test case anyway (this way they're independent and their purpose is documented on the fly) but in this constellation comments would be helpful and time-saving |
||
let i = leb64((1 << 32) - 1, &mut buf); | ||
assert_eq!(buf[..i], [0xff, 0xff, 0xff, 0xff, 0xf]); | ||
buf.iter_mut().for_each(|b| *b = 0x55); | ||
|
||
let i = leb64((1 << 35) - 1, &mut buf); | ||
assert_eq!(buf[..i], [0xff, 0xff, 0xff, 0xff, 0x7f]); | ||
buf.iter_mut().for_each(|b| *b = 0x55); | ||
let i = leb64((1 << 35) - 1, &mut buf); | ||
assert_eq!(buf[..i], [0xff, 0xff, 0xff, 0xff, 0x7f]); | ||
buf.iter_mut().for_each(|b| *b = 0x55); | ||
|
||
let i = leb64(1 << 35, &mut buf); | ||
assert_eq!(buf[..i], [0x80, 0x80, 0x80, 0x80, 0x80, 1]); | ||
buf.iter_mut().for_each(|b| *b = 0x55); | ||
let i = leb64(1 << 35, &mut buf); | ||
assert_eq!(buf[..i], [0x80, 0x80, 0x80, 0x80, 0x80, 1]); | ||
buf.iter_mut().for_each(|b| *b = 0x55); | ||
|
||
let i = leb64((1 << 42) - 1, &mut buf); | ||
assert_eq!(buf[..i], [0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]); | ||
buf.iter_mut().for_each(|b| *b = 0x55); | ||
let i = leb64((1 << 42) - 1, &mut buf); | ||
assert_eq!(buf[..i], [0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]); | ||
buf.iter_mut().for_each(|b| *b = 0x55); | ||
|
||
let i = leb64(u64::max_value(), &mut buf); | ||
assert_eq!( | ||
buf[..i], | ||
[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1] | ||
); | ||
let i = leb64(usize::max_value(), &mut buf); | ||
assert_eq!( | ||
buf[..i], | ||
[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1] | ||
); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the double-shift instead of going for
>>32
right away?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right, should've added a comment for that. Pushed a commit that explains this.