Conversation
cheme
left a comment
There was a problem hiding this comment.
About the PR, removing &db from Raw/Node iterator looks like a good change to me (no need for the suspended, and surely calling it raw makes it clear one can do something wrong with this iterator).
What are the plans for the substrate optim, I remember planning to use the suspended struct in host function to use it again if the start key used in a following next_key call is the same as the previously return key (but don't find back my branch)?
Or is there an idea to use a host api that keep state of iterator (I got in https://github.com/cheme/substrate/tree/transient a host api that keeps a hasher state in memory could be runing similarily)?
Regarding possible substrate optimization, there is one I would find interesting, that would be to switch sp-state-machine backend trait to use &mut on all accesses, thus removing the need for inner mutability (for trie cache and recorder). I started in this direction in paritytech/substrate#13006, but only covered Externalities trait (switching trie backend requires other changes, at least one existing clone to fetch runtime, but it can certainly be avoided). But I think this would not touch the trie crate (recorder and cache being already &mut).
trie-db/src/iterator.rs
Outdated
| &mut self, | ||
| db: &TrieDB<L>, | ||
| ) -> Option< | ||
| Result<(NibbleVec, Option<TrieHash<L>>, Rc<OwnedNode<DBValue>>), TrieHash<L>, CError<L>>, |
There was a problem hiding this comment.
Not related to this pr (just I was a bit surprise when reading the existing code), but really looks like this function should return Result<(&NibbleVec, Option<TrieHash>, Rc<OwnedNode>), TrieHash, CError>,`, quite some key copy involved here. Probably could also get rid of the Rc.
trie-db/src/iterator.rs
Outdated
| Ok((mut prefix, _, node)) => { | ||
| let maybe_value = match node.node() { | ||
| Node::Leaf(partial, value) => { | ||
| prefix.append_partial(partial.right()); |
There was a problem hiding this comment.
Not related to this PR either, but the key building should be done on the raw iter key_nibbles directly.
trie-db/src/triedb.rs
Outdated
| /// Position the iterator on the first element with key >= `key` | ||
| fn seek(&mut self, key: &[u8]) -> Result<(), TrieHash<L>, CError<L>> { | ||
| TrieIterator::seek(&mut self.inner, key) | ||
| self.raw_iter.seek_prefix(self.db, key).map(|_| ()) |
There was a problem hiding this comment.
I am wondering if the function for raw_iter seek_prefix should be rename (I am maybe the one that give this ~ naming in the first place ). Here it just does a seek key which is what we need, but I had to check the code to be sure it is not the variant that seek a key and then remove nodes from the stack so it limits remaining iteration to the prefix.
wasn't it the case already? |
Does the suspended approach not work (I remember putting something in place but probably drop it at some point, not sure why)? |
For now I'm mostly just simplifying the way we do iteration; e.g. the So it is essentially the suspend approach, it just needs these changes to make it fully possible (not everything was originally exported the first time I tried it IIRC) and simpler. In general for now my main objective is to just simplify and remove dangerous methods (those which return a
Hmm.... is this actually going to affect the performance in a substantial way?
Previously they had their dedicated |
Not sure about perf, actually recorder and cache are already behind a refcell in the trie crate. Would still make sense to me to just plain &mut ptr for read access operation and get rid of as much inner mutability as possible, but that is a different question. |
|
@cheme Okay, I resurrected the fuzz tests (they didn't compile due to too old version of a dependency in The logic's unchanged and I didn't touch the extra clones. You're right that we should be able to refactor it so that it appends to the |
|
yes the fuzzer is quite often a bit behind, thanks.
I did check a bit, we probably want to return the key_nibbles after the partial (append the partial on |
davxy
left a comment
There was a problem hiding this comment.
Not a trie guru. But codewise looks good
|
Missed you by a few second, but trie-bench changelog can also be updated (not really important tbh), otherwhise latest changes still looks good. |
Ah, sorry, I didn't realize that one's also released on crates.io. I'll update it. |
This PR simplifies and refactors the iterators in
trie-db.The changes can be summarized as follows:
TrieDBNodeIterator-likeTrieDBRawIteratorand made it lifetimeless (instead of storing a&TrieDBit now takes it as a parameter during the iteration)SuspendedTrieDBKeyIteratorwas removed since theTrieDBRawIteratoris a complete replacement for it (with the added bonus that it can be iterated on)TrieDBIterator::nextandTrieDBKeyIterator::nextwere renamed and moved intoTrieDBRawIteratorwith no changes to the logic (except making them use&TrieDBpassed as a parameter instead of the one stored inself, and cleaning them up slightly)TrieDBIteratorandTrieDBKeyIteratornow useTrieDBRawIteratorunder the hood#[inline]s were added to make recreating a&TrieDBon each iteration into a zero-cost operationThis makes further refactoring of storage iterators in
substratepossible.