Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Creating fully detached copy of trie #2072

Unanswered
faustbrian asked this question in Q&A
Discussion options

So my use-case for one scenario in my application is that I want to create a copy of a trie and then operate on that copy for a while without persisting anything to the underlying database. Now the issue is that when you call copy on a trie instance that uses a database that persists the disk (like level with a path argument) then the copy of the trie will also operate based on that database and thus modify it on disk if you perform any writes (unless I'm missing or misunderstanding something).

So my question is if there's any way to create transient trie copies that don't write to the database or if there's some other recommended best practice to achieve this? I basically need something like trie.copyAsReadOnly(); where the trie still behaves as normal but it'll never perform any write operations against the database on this copy, thus leaving the underlying database on the filesystem untouched. Read-only in this context refers to the filesystem, not in-memory data.

TL;DR of my use-case is that I want to apply state changes to the copy of a trie but the copy only exists for a few seconds before the state changes are written to the real trie, at which point the copy is recreated and the cycle repeats. That's why the copy can't be allowed to write to the filesystem because the real trie has to stay untouched in order for that work as intended.

Example

The below code is a simplified view of what is happening in my application. The copy is recreated every time all changes have been applied, excluding those changes that triggered the catch block. The important part is that under no circumstances do we want the changes to the trie to be written to disk.

const copy = real.copy();

for (const change of changes) {
    try {
        await copy.checkpoint();

        // We don't want the changes from the execution to be written to disk
        // because this will call 'put' dozens of times but we only care about
        // the state resulting from that, not about persisting it because we
        // will persist it later on by executing the same data against the 'real'
        // trie which will then persist it and we're done with applying changes
        change.mutate(copy);

        await copy.commit();
    } catch {
        await copy.revert();
    }
}

The changes depend on each other so for example changes[0] might mutate an object and changes[3] wants to mutate the same object but because of what changes[0] did it'll either skip doing what it wants to do or trigger the catch block and revert to the previous checkpoint. I need to apply all changes sequentially to mirror how they will be applied once they pass on the copy of the trie.

Checkpoints

One possible approach I thought about was to use checkpoints but my use-case requires that I'm able to create, commit and revert checkpoints on the copy of the trie because even though the state changes that are being applied are transient there's many that are applied and if one of them fails it needs to be possible to revert to the checkpoint before that state change to ignore it and continue. So this basically eliminates checkpoints as an option because as soon as I call commit everything will be written to the disk. Maybe there is some way to abuse nested checkpoints to achieve what I want?

You must be logged in to vote

Replies: 2 comments

Comment options

Might be able to abuse nested checkpoints for this. Writing some tests that can serve as documentation for it. I'll submit a PR for them in the next days.

You must be logged in to vote
0 replies
Comment options

I would be open to have this added to the API in some form, can't we do something like you suggested with a separate copy function and then copy over the DB to a new in-memory DB or something like that?

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
2 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.