Skip to content
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

BitVec: Improve the encoding and consolidate the implementations #327

Merged
merged 6 commits into from
Mar 17, 2022

Conversation

bkchr
Copy link
Member

@bkchr bkchr commented Mar 16, 2022

No description provided.

src/bit_vec.rs Outdated Show resolved Hide resolved
Comment on lines -25 to -28
impl<O: BitOrder, T: BitStore> Encode for BitSlice<T, O>
where
T::Mem: Encode
{
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This technically is semver breaking, but I would go this route. BitVec already required the same bound.

@jsdw
Copy link
Contributor

jsdw commented Mar 16, 2022

In general, the tests don't really look like they test that the bitvec is still being encoded in the same binary format as previously, only that it can be encoded and decoded back and still be equal. Is it worth adding a couple of tests to check that the SCALE encoded bytes are what we expect, too?

Copy link
Contributor

@dvdplm dvdplm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A before/after test like James suggests is a good idea to add.

for element in self.domain() {
// Iterate over chunks
for chunk in self.chunks(core::mem::size_of::<T>() * 8) {
let mut element = T::ZERO;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be moved outside the loop perhaps and re-used? Or will the compiler re-use element anyway?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be wrong. As the last chunk could have less bits than the ones before, we could end up with an element having bits set that should not be set. I mean that should be fixed on the decoding side. However, I also don't see any real performance issue with having the primitive type inside the loop.

@dvdplm dvdplm requested a review from ascjones March 16, 2022 16:24
tests/mod.rs Show resolved Hide resolved
src/bit_vec.rs Show resolved Hide resolved
@bkchr
Copy link
Member Author

bkchr commented Mar 16, 2022

In general, the tests don't really look like they test that the bitvec is still being encoded in the same binary format as previously, only that it can be encoded and decoded back and still be equal. Is it worth adding a couple of tests to check that the SCALE encoded bytes are what we expect, too?

The old encode was wrong. It would have lead to decode decoding junk. This is now fixed and the expected encoding format didn't changed.

@jsdw
Copy link
Contributor

jsdw commented Mar 16, 2022

Yup, of course in some cases it was broken previously. But it would be nice to have a couple of tests to check that the encoding format is what we are expecting it to be in other places, for example that bitvec![u8, Lsb0, 0, 0, 1, 1] encodes to the same as (Compact<u32>(4), 3u8) (or whatever the correct encoding would be).

Actually, I had a play myself and this naive test:

#[test]
fn bitvec_u8_encodes_as_expected() {
	let cases = vec![
		(bitvec![u8, Lsb0; 0, 0, 1, 1].encode(), (Compact(4u32), 0b00001100u8).encode()),
		(bitvec![u8, Lsb0; 0, 1, 1, 1].encode(), (Compact(4u32), 0b00001110u8).encode()),
		(bitvec![u8, Lsb0; 1, 1, 1, 1].encode(), (Compact(4u32), 0b00001111u8).encode()),
		(bitvec![u8, Lsb0; 1, 1, 1, 1, 1].encode(), (Compact(5u32), 0b00011111u8).encode()),
		(bitvec![u8, Lsb0; 1, 1, 1, 1, 1, 0].encode(), (Compact(6u32), 0b00011111u8).encode()),
	];

	for (idx, (actual, expected)) in cases.into_iter().enumerate() {
		assert_eq!(actual, expected, "case at index {idx} failed; encodings differ");
	}
}

seemed to pass equally before and after the change, which gives me some confidence that the SCALE format is identical (of course it could be extended towork with different orderings and store types) :)

@bkchr
Copy link
Member Author

bkchr commented Mar 16, 2022

CI is green.

@bkchr
Copy link
Member Author

bkchr commented Mar 16, 2022

seemed to pass equally before and after the change, which gives me some confidence that the SCALE format is identical (of course it could be extended towork with different orderings and store types) :)

I added the test. However, it was already ensured that the format didn't changed, because we don't have changed the Decode implementation.

@bkchr
Copy link
Member Author

bkchr commented Mar 16, 2022

bot merge

@bkchr bkchr merged commit 372d617 into master Mar 17, 2022
@bkchr bkchr deleted the bkchr-improve-bitvec branch March 17, 2022 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants