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

Implement DecodeWithMemTracking for BoundedBTreeMap #906

Merged
merged 8 commits into from
Mar 20, 2025

Conversation

seadanda
Copy link
Contributor

@seadanda seadanda commented Mar 14, 2025

Implement DecodeWithMemTracking for BoundedBTreeMap and release bounded collections as 0.2.4.

@seadanda seadanda requested a review from serban300 March 14, 2025 10:45
@seadanda seadanda requested a review from a team as a code owner March 14, 2025 10:56
@seadanda
Copy link
Contributor Author

CI should probably be using --locked, as it passed on master a month ago but fails now due to some minimum rust version requirements from dependencies.
Also should bump the rust-version of a lot of packages, since a quick look shows that some packages are at 1.56 which is unlikely to actually work. Probably best to lift it to the workspace level and set it to 1.81 for all

@@ -1,6 +1,6 @@
[package]
name = "bounded-collections"
version = "0.2.3"
version = "0.2.4"
description = "Bounded types and their supporting traits"
readme = "README.md"
rust-version = "1.79.0"
Copy link
Member

Choose a reason for hiding this comment

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

bump this to 1.81?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I went through the workspace members and found the following rust versions to be the minimum:

members = [
	"fixed-hash", # 1.64
	"keccak-hash", # 1.79
	"kvdb", # 1.64
	"kvdb-memorydb", # 1.64
	"kvdb-rocksdb", # 1.71.1
	"kvdb-shared-tests", # 1.64
	"parity-bytes", # 1.64
	"rlp", # 1.64
	"rlp-derive", # 1.64
	"uint", # 1.64
	"primitive-types", # 1.79
	"bounded-collections", # 1.79
	"ethereum-types", # 1.79
	"ethbloom", # 1.64
]

1.64 is the minimum for the whole workspace since before this the cargo manifest requires author to be a different format.
weirdly for the individual packages I don't see the requirement for 1.81, so I wonder if there are some unused deps at the workspace level

Copy link
Member

Choose a reason for hiding this comment

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

You can use cargo msrv just to check that it works with that.
We should also have this in CI actually.

@@ -123,6 +123,14 @@ where
}
}

impl<K, V, S> DecodeWithMemTracking for BoundedBTreeMap<K, V, S>
Copy link
Contributor

@serban300 serban300 Mar 14, 2025

Choose a reason for hiding this comment

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

I thought that BoundedBtreeMap is just a wrapper over BTreeMap, but I see it has its own implementation for decode. So we should do the same as for BTreeMap in the decoding logic: https://github.com/paritytech/parity-scale-codec/blob/8d65d28e778d914988849b786c17216070ecd9a1/src/codec.rs#L1273

@niklasad1
Copy link
Member

niklasad1 commented Mar 14, 2025

CI should probably be using --locked, as it passed on master a month ago but fails now due to some minimum rust version requirements from dependencies.
Also should bump the rust-version of a lot of packages, since a quick look shows that some packages are at 1.56 which is unlikely to actually work. Probably best to lift it to the workspace level and set it to 1.81 for all

--locked doesn't fix it because Cargo.lock is not committed to this repo because it only contains library crates. We could maybe commit Cargo.lock just to avoid such scenarios because it's possible to workaround this as a user by doing cargo update -p zerofrom --precise <VERSION>

@seadanda
Copy link
Contributor Author

Ah ok that makes sense, haven't worked in this repo before. Thanks for the context

@seadanda
Copy link
Contributor Author

WIP until paritytech/parity-scale-codec#721 is released

Comment on lines 115 to 118
input.descend_ref()?;
input.on_before_alloc_mem(codec::mem_size_of_btree::<(K, V)>(len))?;
let inner = Result::from_iter((0..len).map(|_| Decode::decode(input)))?;
input.ascend_ref();
Copy link
Member

Choose a reason for hiding this comment

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

Should be replaced by

struct PrependCompactInput { compact: Compact<u32>, read: u32, inner: I }

/// impl Input that first prepends the compact and then uses the inner

/// After that you use it

let inner = BTreeMap::decode(&mut PrependCompactInput { compact, read: 0, inner: input })?

Copy link
Contributor Author

@seadanda seadanda Mar 18, 2025

Choose a reason for hiding this comment

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

Nice idea, implemented as you've described it in 1a73132

Depending on how hard we want to go we could maybe avoid some allocations since Compact<u32> has a fixed upper limit on its size with something like:

struct PrependCompactInput<'a, I> {
    compact_bytes: [u8; 5],
    compact_len: u8,
    read: u32,
    inner: &'a mut I,
}

Then you just encode the compact once instead of on each read. When we construct the struct we dump the encoded compact into this array and hardcode its length, so we know only the first compact_len bytes are valid

return self.inner.read(into);
}

let to_read = into.len().min(remaining_compact);
Copy link
Member

Choose a reason for hiding this comment

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

You also need to have loop, because into.len() is mayber bigger than remaining_compact. The read function requires that all the requested bytes are filled.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just got around to fixing this in 908af22 and added tests. Should be good to go now

@seadanda seadanda requested review from serban300 and bkchr March 20, 2025 15:43
}
} else {
// Prepended compact has been read, just read from inner.
self.inner.read(into)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't increase the PrependCompactInput read counter after the compact has been fully read as it's pointless to track any more.

Copy link
Member

@bkchr bkchr left a comment

Choose a reason for hiding this comment

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

Ty Ser!

@bkchr bkchr merged commit d3e826f into master Mar 20, 2025
6 checks passed
@bkchr bkchr deleted the donal-boundedbtreemap-memtracking branch March 20, 2025 20:16
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.

6 participants