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

feat: replace the node key #597

Closed
wants to merge 15 commits into from
Closed

Conversation

cool-develope
Copy link
Collaborator

ref: #592

@cool-develope cool-develope requested a review from a team as a code owner October 25, 2022 19:22
@cool-develope cool-develope marked this pull request as draft October 25, 2022 19:22
@lgtm-com
Copy link
Contributor

lgtm-com bot commented Oct 25, 2022

This pull request introduces 5 alerts when merging f3168eb into 7204160 - view on LGTM.com

new alerts:

  • 5 for Missing error check

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Oct 26, 2022

This pull request fixes 1 alert when merging 35c73c5 into 7204160 - view on LGTM.com

fixed alerts:

  • 1 for Unreachable statement

@cool-develope cool-develope marked this pull request as ready for review October 28, 2022 20:56
@lgtm-com
Copy link
Contributor

lgtm-com bot commented Oct 28, 2022

This pull request fixes 1 alert when merging 36a150e into 7204160 - view on LGTM.com

fixed alerts:

  • 1 for Unreachable statement

@tac0turtle
Copy link
Member

before final merge could we get an adr describing these changes and then also the removal of orphan system. It would help with objective and delivery items.

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Oct 31, 2022

This pull request fixes 1 alert when merging 37fe66f into 7204160 - view on LGTM.com

fixed alerts:

  • 1 for Unreachable statement


It requires extra storage to store the node because it should keep `leftNodeKey` and `rightNodeKey` to iterate the tree. Instead, we can delete the `version` in the node and reduce the key size.

It can't delete the old nodes for the specific version due to removing orphans. But it makes `rollback` easier and it makes it possible to remove old nodes through `import` and `export` functionalities. The `export` will restruct the tree to make node IDs to a sequenced segment like (1 ... node_sieze).
Copy link
Member

Choose a reason for hiding this comment

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

If there 50 versions, are we still able to remove version 5-10?

docs/architecture/adr-001-node-key-refactoring.md Outdated Show resolved Hide resolved
@aaronc
Copy link
Member

aaronc commented Nov 2, 2022

Do you can have comparative benchmarks you can show for this @cool-develope?

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Nov 3, 2022

This pull request fixes 1 alert when merging 042b877 into 7204160 - view on LGTM.com

fixed alerts:

  • 1 for Unreachable statement

@tac0turtle
Copy link
Member

its a bit odd how variable the benchmarks are.

are we able to get some profiles on the changes?

mutable_tree.go Outdated
@@ -31,7 +30,7 @@ var ErrVersionDoesNotExist = errors.New("version does not exist")
type MutableTree struct {
*ImmutableTree // The current, working tree.
lastSaved *ImmutableTree // The most recently saved tree.
orphans map[string]int64 // Nodes removed by changes to working tree.
orphans map[int64]int64 // Nodes removed by changes to working tree.
Copy link
Member

Choose a reason for hiding this comment

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

Why do we still need orphans? Are there plans to remove them in a subsequent PR?

Copy link
Member

Choose a reason for hiding this comment

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

the idea is to remove them, this wasn't done in this pr

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Nov 25, 2022

This pull request fixes 1 alert when merging 43dcaff into 7204160 - view on LGTM.com

fixed alerts:

  • 1 for Unreachable statement

Heads-up: LGTM.com's PR analysis will be disabled on the 5th of December, and LGTM.com will be shut down ⏻ completely on the 16th of December 2022. It looks like GitHub code scanning with CodeQL is already set up for this repo, so no further action is needed 🚀. For more information, please check out our post on the GitHub blog.

return false
})
return size
return int(t.root.size*2 - 1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is only correct if the tree is a full one?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

right, this API is only used for the test purpose right now

mutable_tree.go Outdated
// We don't need to orphan nodes that were never persisted.
continue
// getOrphans gets orphaned nodes by the changes of the working tree.
func (tree *MutableTree) getOrphans() []*NodeKey {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't see how you can track the orphans try traverse the prev root?

Copy link
Collaborator Author

@cool-develope cool-develope Nov 25, 2022

Choose a reason for hiding this comment

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

it is related to node.Clone(), as you can see I added the ensure part to assign children in Clone function.
If the node of the lastSaved tree has children, it means it is orphaned in the current version

Copy link
Collaborator

@yihuang yihuang Nov 25, 2022

Choose a reason for hiding this comment

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

I guess you also need to clear those reference to avoid memory leak?
And the nodes come from NodeDB's cache, could it be evicted by cache and load again from db?
Somehow it don't feels cleaner than previous solution to me.
If we can somehow track orphans by traversing new root and old root simultaneously, without "hacking" the old nodes, that'd be ideal.

Copy link
Collaborator

@yihuang yihuang Nov 25, 2022

Choose a reason for hiding this comment

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

If you assume cloning a node means orphan it (let's assume the assumption is correct for now), how about simply mark it with a flag?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

it could be, I will check it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

OK, it works, I updated it.

@cool-develope
Copy link
Collaborator Author

here it the benchmarking result

name                                                                             old time/op    new time/op    delta
Large/memdb-1000000-100-16-40/query-no-in-tree-guarantee-fast-8                    5.17µs ±36%    5.18µs ±18%      ~     (p=0.496 n=20+18)
Large/memdb-1000000-100-16-40/query-no-in-tree-guarantee-slow-8                    29.5µs ±32%    22.3µs ±12%   -24.38%  (p=0.000 n=20+18)
Large/memdb-1000000-100-16-40/query-hits-fast-8                                    6.63µs ±10%    7.23µs ±16%    +9.01%  (p=0.006 n=19+20)
Large/memdb-1000000-100-16-40/query-hits-slow-8                                    33.2µs ±25%    28.5µs ±15%   -14.14%  (p=0.000 n=19+20)
Large/memdb-1000000-100-16-40/iteration-fast-8                                      765ms ±21%     733ms ±22%      ~     (p=0.296 n=20+19)
Large/memdb-1000000-100-16-40/iteration-slow-8                                      17.9s ±11%      7.2s ±14%   -59.50%  (p=0.000 n=19+20)
Large/memdb-1000000-100-16-40/update-8                                              437µs ±25%     282µs ±14%   -35.59%  (p=0.000 n=20+18)
Large/memdb-1000000-100-16-40/block-8                                              50.4ms ±14%    31.7ms ±10%   -37.09%  (p=0.000 n=19+18)
Large/goleveldb-1000000-100-16-40/query-no-in-tree-guarantee-fast-8                11.9µs ±19%    11.4µs ±29%    -4.68%  (p=0.044 n=20+19)
Large/goleveldb-1000000-100-16-40/query-no-in-tree-guarantee-slow-8                35.5µs ±14%    35.6µs ±27%      ~     (p=0.863 n=16+20)
Large/goleveldb-1000000-100-16-40/query-hits-fast-8                                13.8µs ±19%    13.7µs ±17%      ~     (p=0.753 n=18+19)
Large/goleveldb-1000000-100-16-40/query-hits-slow-8                                50.1µs ±18%    46.9µs ±21%      ~     (p=0.056 n=20+20)
Large/goleveldb-1000000-100-16-40/iteration-fast-8                                  940ms ±29%     989ms ±27%      ~     (p=0.165 n=20+20)
Large/goleveldb-1000000-100-16-40/iteration-slow-8                                  33.6s ±10%     15.3s ±13%   -54.36%  (p=0.000 n=17+19)
Large/goleveldb-1000000-100-16-40/update-8                                          490µs ±25%     324µs ±17%   -33.96%  (p=0.000 n=20+19)
Large/goleveldb-1000000-100-16-40/block-8                                          68.1ms ±30%    38.9ms ±22%   -42.85%  (p=0.000 n=20+19)
LevelDBLargeData/goleveldb-50000-100-32-100/query-no-in-tree-guarantee-fast-8      5.46µs ±15%    6.27µs ±39%   +14.79%  (p=0.000 n=37+39)
LevelDBLargeData/goleveldb-50000-100-32-100/query-no-in-tree-guarantee-slow-8      20.0µs ±29%    20.4µs ±30%      ~     (p=0.584 n=39+37)
LevelDBLargeData/goleveldb-50000-100-32-100/query-hits-fast-8                       686ns ±25%     769ns ±25%   +12.17%  (p=0.000 n=38+40)
LevelDBLargeData/goleveldb-50000-100-32-100/query-hits-slow-8                      25.6µs ±12%    29.9µs ±36%   +16.45%  (p=0.000 n=36+38)
LevelDBLargeData/goleveldb-50000-100-32-100/iteration-fast-8                       61.5ms ±18%    66.1ms ±24%    +7.47%  (p=0.004 n=39+40)
LevelDBLargeData/goleveldb-50000-100-32-100/iteration-slow-8                        1.10s ±21%     0.88s ±29%   -19.60%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-100/update-8                                257µs ±24%     278µs ±38%    +8.14%  (p=0.015 n=36+40)
LevelDBLargeData/goleveldb-50000-100-32-100/block-8                                38.9ms ±30%    32.2ms ±27%   -17.25%  (p=0.000 n=40+39)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-no-in-tree-guarantee-fast-8     10.9µs ±20%    12.1µs ±23%   +11.48%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-no-in-tree-guarantee-slow-8     23.2µs ±23%    27.1µs ±28%   +17.00%  (p=0.000 n=37+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-hits-fast-8                      704ns ±20%     763ns ±27%    +8.33%  (p=0.001 n=38+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-hits-slow-8                     32.4µs ±24%    38.7µs ±39%   +19.50%  (p=0.000 n=39+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/iteration-fast-8                       194ms ±19%     204ms ±28%      ~     (p=0.140 n=39+39)
LevelDBLargeData/goleveldb-50000-100-32-1000/iteration-slow-8                       1.29s ±15%     1.09s ±25%   -15.72%  (p=0.000 n=37+38)
LevelDBLargeData/goleveldb-50000-100-32-1000/update-8                               398µs ±33%     380µs ±37%      ~     (p=0.312 n=35+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/block-8                               81.4ms ±70%    45.3ms ±38%   -44.43%  (p=0.000 n=40+39)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-no-in-tree-guarantee-fast-8    23.3µs ±18%    25.8µs ±22%   +10.59%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-no-in-tree-guarantee-slow-8    35.0µs ±17%    55.6µs ±32%   +59.08%  (p=0.000 n=38+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-hits-fast-8                     702ns ±26%     779ns ±41%   +11.03%  (p=0.001 n=40+37)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-hits-slow-8                    48.6µs ±17%    70.0µs ±25%   +44.01%  (p=0.000 n=37+36)
LevelDBLargeData/goleveldb-50000-100-32-10000/iteration-fast-8                      843ms ±14%    1219ms ±63%   +44.55%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/iteration-slow-8                      2.32s ±21%     3.34s ±23%   +44.12%  (p=0.000 n=38+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/update-8                             2.31ms ±49%    2.17ms ±51%      ~     (p=0.144 n=38+39)
LevelDBLargeData/goleveldb-50000-100-32-10000/block-8                               279ms ±37%     252ms ±42%    -9.57%  (p=0.020 n=39+33)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-no-in-tree-guarantee-fast-8       4.98µs ±14%    5.83µs ±16%   +17.08%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-no-in-tree-guarantee-slow-8       21.9µs ±17%    24.8µs ±27%   +13.35%  (p=0.003 n=20+20)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-hits-fast-8                        762ns ±14%     903ns ±20%   +18.59%  (p=0.000 n=18+20)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-hits-slow-8                       29.6µs ±22%    31.0µs ±19%      ~     (p=0.224 n=20+19)
LevelDBBatchSizes/goleveldb-100000-5-16-40/iteration-fast-8                         107ms ±39%     100ms ±26%      ~     (p=0.627 n=20+19)
LevelDBBatchSizes/goleveldb-100000-5-16-40/iteration-slow-8                         2.33s ±13%     1.45s ±18%   -37.85%  (p=0.000 n=20+18)
LevelDBBatchSizes/goleveldb-100000-5-16-40/update-8                                 479µs ±23%     457µs ±26%      ~     (p=0.123 n=19+19)
LevelDBBatchSizes/goleveldb-100000-5-16-40/block-8                                 2.76ms ±22%    2.54ms ±38%    -7.86%  (p=0.033 n=19+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-no-in-tree-guarantee-fast-8      5.09µs ± 9%    5.42µs ±29%      ~     (p=0.201 n=20+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-no-in-tree-guarantee-slow-8      23.5µs ±20%    22.9µs ±20%      ~     (p=0.529 n=20+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-hits-fast-8                       779ns ±15%    1052ns ±33%   +34.97%  (p=0.000 n=19+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-hits-slow-8                      28.9µs ±23%    30.9µs ±34%      ~     (p=0.191 n=19+19)
LevelDBBatchSizes/goleveldb-100000-25-16-40/iteration-fast-8                       89.4ms ±20%   104.8ms ±24%   +17.22%  (p=0.000 n=18+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/iteration-slow-8                        2.28s ±15%     1.56s ±18%   -31.58%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/update-8                                338µs ±26%     300µs ±32%   -11.39%  (p=0.001 n=19+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/block-8                                10.4ms ±15%     9.5ms ±21%    -8.83%  (p=0.001 n=18+18)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-no-in-tree-guarantee-fast-8     5.21µs ±17%    5.82µs ±26%   +11.71%  (p=0.003 n=20+19)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-no-in-tree-guarantee-slow-8     21.0µs ±16%    21.6µs ±15%      ~     (p=0.235 n=19+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-hits-fast-8                      821ns ±24%     931ns ±31%   +13.47%  (p=0.003 n=18+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-hits-slow-8                     29.4µs ±11%    30.6µs ±24%      ~     (p=0.460 n=18+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/iteration-fast-8                      85.0ms ±16%    93.3ms ±25%    +9.69%  (p=0.022 n=19+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/iteration-slow-8                       2.28s ±12%     1.49s ±11%   -34.50%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-100-16-40/update-8                               288µs ±26%     272µs ±28%      ~     (p=0.325 n=19+19)
LevelDBBatchSizes/goleveldb-100000-100-16-40/block-8                               40.6ms ±16%    32.5ms ±25%   -20.06%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-no-in-tree-guarantee-fast-8     5.02µs ±11%    5.44µs ±19%    +8.48%  (p=0.005 n=18+19)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-no-in-tree-guarantee-slow-8     22.0µs ±15%    21.7µs ±26%      ~     (p=0.242 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-hits-fast-8                      815ns ±24%     880ns ±28%      ~     (p=0.158 n=19+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-hits-slow-8                     33.9µs ±39%    28.1µs ±20%   -16.93%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-400-16-40/iteration-fast-8                      87.5ms ±14%    92.1ms ±19%      ~     (p=0.204 n=19+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/iteration-slow-8                       2.37s ±20%     1.46s ±14%   -38.35%  (p=0.000 n=20+19)
LevelDBBatchSizes/goleveldb-100000-400-16-40/update-8                               305µs ±23%     286µs ±26%      ~     (p=0.223 n=19+19)
LevelDBBatchSizes/goleveldb-100000-400-16-40/block-8                                157ms ±14%     133ms ±25%   -15.15%  (p=0.000 n=18+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-no-in-tree-guarantee-fast-8    4.95µs ±13%    5.50µs ±32%   +11.10%  (p=0.006 n=18+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-no-in-tree-guarantee-slow-8    22.3µs ±17%    25.8µs ±23%   +15.41%  (p=0.004 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-hits-fast-8                     899ns ±32%     888ns ±24%      ~     (p=0.738 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-hits-slow-8                    32.5µs ±28%    29.7µs ±30%    -8.58%  (p=0.020 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/iteration-fast-8                     88.7ms ±20%    82.2ms ±10%      ~     (p=0.060 n=20+17)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/iteration-slow-8                      2.46s ±27%     1.53s ±20%   -37.77%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/update-8                              282µs ±38%     208µs ±43%   -26.23%  (p=0.001 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/block-8                               883ms ±22%     559ms ±17%   -36.73%  (p=0.000 n=19+20)

name                                                                             old alloc/op   new alloc/op   delta
Large/memdb-1000000-100-16-40/query-no-in-tree-guarantee-fast-8                     88.0B ± 0%     88.0B ± 0%      ~     (all equal)
Large/memdb-1000000-100-16-40/query-no-in-tree-guarantee-slow-8                      460B ±54%      854B ± 6%   +85.67%  (p=0.000 n=18+16)
Large/memdb-1000000-100-16-40/query-hits-fast-8                                      210B ± 2%      210B ± 2%      ~     (p=0.711 n=17+18)
Large/memdb-1000000-100-16-40/query-hits-slow-8                                      582B ± 1%     1077B ± 1%   +85.19%  (p=0.000 n=20+20)
Large/memdb-1000000-100-16-40/iteration-fast-8                                      232MB ± 0%     232MB ± 0%      ~     (p=0.941 n=18+16)
Large/memdb-1000000-100-16-40/iteration-slow-8                                      824MB ± 0%    1096MB ± 0%   +33.01%  (p=0.000 n=18+16)
Large/memdb-1000000-100-16-40/update-8                                             36.0kB ± 2%    37.5kB ± 2%    +4.03%  (p=0.000 n=18+19)
Large/memdb-1000000-100-16-40/block-8                                              3.67MB ± 0%    3.76MB ± 0%    +2.36%  (p=0.000 n=19+20)
Large/goleveldb-1000000-100-16-40/query-no-in-tree-guarantee-fast-8                  993B ± 0%      993B ± 0%      ~     (all equal)
Large/goleveldb-1000000-100-16-40/query-no-in-tree-guarantee-slow-8                2.21kB ±59%    2.44kB ±40%   +10.30%  (p=0.030 n=19+19)
Large/goleveldb-1000000-100-16-40/query-hits-fast-8                                1.04kB ± 1%    1.03kB ± 1%    -1.20%  (p=0.000 n=18+19)
Large/goleveldb-1000000-100-16-40/query-hits-slow-8                                2.67kB ± 1%    3.01kB ± 1%   +12.87%  (p=0.000 n=20+19)
Large/goleveldb-1000000-100-16-40/iteration-fast-8                                  297MB ± 0%     297MB ± 0%    -0.01%  (p=0.000 n=19+15)
Large/goleveldb-1000000-100-16-40/iteration-slow-8                                 3.63GB ± 0%    2.53GB ± 0%   -30.45%  (p=0.000 n=18+18)
Large/goleveldb-1000000-100-16-40/update-8                                         84.3kB ±12%    55.3kB ±11%   -34.37%  (p=0.000 n=19+20)
Large/goleveldb-1000000-100-16-40/block-8                                          10.8MB ±14%     5.8MB ±15%   -46.35%  (p=0.000 n=20+20)
LevelDBLargeData/goleveldb-50000-100-32-100/query-no-in-tree-guarantee-fast-8        936B ± 0%      936B ± 0%      ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-100/query-no-in-tree-guarantee-slow-8      1.45kB ± 1%    1.73kB ± 1%   +19.56%  (p=0.000 n=39+37)
LevelDBLargeData/goleveldb-50000-100-32-100/query-hits-fast-8                       0.00B          0.00B           ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-100/query-hits-slow-8                      2.05kB ± 1%    2.35kB ± 1%   +14.28%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-100/iteration-fast-8                       25.1MB ± 0%    25.1MB ± 0%    +0.00%  (p=0.000 n=39+39)
LevelDBLargeData/goleveldb-50000-100-32-100/iteration-slow-8                        141MB ± 0%     143MB ± 0%    +1.26%  (p=0.000 n=39+39)
LevelDBLargeData/goleveldb-50000-100-32-100/update-8                               43.5kB ± 5%    39.2kB ± 3%    -9.92%  (p=0.000 n=39+35)
LevelDBLargeData/goleveldb-50000-100-32-100/block-8                                5.71MB ±17%    4.64MB ±20%   -18.68%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-no-in-tree-guarantee-fast-8     2.07kB ± 0%    2.07kB ± 0%      ~     (p=0.261 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-no-in-tree-guarantee-slow-8     2.48kB ± 1%    2.76kB ± 1%   +11.27%  (p=0.000 n=40+38)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-hits-fast-8                      0.00B          0.00B           ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-hits-slow-8                     3.52kB ± 1%    3.82kB ± 1%    +8.29%  (p=0.000 n=39+38)
LevelDBLargeData/goleveldb-50000-100-32-1000/iteration-fast-8                       126MB ± 0%     126MB ± 0%      ~     (p=0.996 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/iteration-slow-8                       246MB ± 0%     242MB ± 0%    -1.76%  (p=0.000 n=38+38)
LevelDBLargeData/goleveldb-50000-100-32-1000/update-8                              70.4kB ± 9%    62.7kB ± 4%   -10.87%  (p=0.000 n=39+36)
LevelDBLargeData/goleveldb-50000-100-32-1000/block-8                               11.1MB ±13%     8.0MB ±12%   -27.52%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-no-in-tree-guarantee-fast-8    12.8kB ± 0%    12.8kB ± 0%    +0.21%  (p=0.000 n=36+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-no-in-tree-guarantee-slow-8    12.8kB ± 2%    12.0kB ± 2%    -6.19%  (p=0.000 n=40+39)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-hits-fast-8                     0.00B          0.00B           ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-hits-slow-8                    18.3kB ± 1%    17.1kB ± 1%    -6.52%  (p=0.000 n=39+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/iteration-fast-8                     1.06GB ± 0%    1.06GB ± 0%    +0.00%  (p=0.010 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/iteration-slow-8                     1.30GB ± 0%    1.17GB ± 0%   -10.14%  (p=0.000 n=38+38)
LevelDBLargeData/goleveldb-50000-100-32-10000/update-8                              298kB ± 8%     250kB ± 5%   -16.12%  (p=0.000 n=39+37)
LevelDBLargeData/goleveldb-50000-100-32-10000/block-8                              47.0MB ±11%    35.0MB ±11%   -25.52%  (p=0.000 n=39+36)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-no-in-tree-guarantee-fast-8         790B ± 0%      790B ± 0%      ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-no-in-tree-guarantee-slow-8       1.38kB ± 1%    1.77kB ± 1%   +28.54%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-hits-fast-8                        0.00B          0.00B           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-hits-slow-8                       1.97kB ± 1%    2.42kB ± 1%   +22.77%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-5-16-40/iteration-fast-8                        29.3MB ± 0%    29.3MB ± 0%      ~     (p=0.447 n=19+18)
LevelDBBatchSizes/goleveldb-100000-5-16-40/iteration-slow-8                         270MB ± 0%     253MB ± 0%    -6.07%  (p=0.000 n=18+17)
LevelDBBatchSizes/goleveldb-100000-5-16-40/update-8                                67.1kB ± 6%    52.6kB ± 3%   -21.55%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-5-16-40/block-8                                  371kB ± 5%     277kB ± 4%   -25.22%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-no-in-tree-guarantee-fast-8        790B ± 0%      790B ± 0%      ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-no-in-tree-guarantee-slow-8      1.37kB ± 1%    1.77kB ± 1%   +28.94%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-hits-fast-8                       0.00B          0.00B           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-hits-slow-8                      1.97kB ± 1%    2.42kB ± 1%   +22.83%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/iteration-fast-8                       29.3MB ± 0%    29.3MB ± 0%    +0.00%  (p=0.005 n=18+17)
LevelDBBatchSizes/goleveldb-100000-25-16-40/iteration-slow-8                        270MB ± 0%     253MB ± 0%    -6.26%  (p=0.000 n=16+16)
LevelDBBatchSizes/goleveldb-100000-25-16-40/update-8                               54.6kB ± 4%    44.7kB ± 3%   -18.08%  (p=0.000 n=18+18)
LevelDBBatchSizes/goleveldb-100000-25-16-40/block-8                                1.57MB ± 4%    1.26MB ± 8%   -20.12%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-no-in-tree-guarantee-fast-8       790B ± 0%      790B ± 0%      ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-no-in-tree-guarantee-slow-8     1.38kB ± 2%    1.77kB ± 1%   +28.41%  (p=0.000 n=20+19)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-hits-fast-8                      0.00B          0.00B           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-hits-slow-8                     1.98kB ± 1%    2.42kB ± 1%   +22.36%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/iteration-fast-8                      29.3MB ± 0%    29.3MB ± 0%    -0.00%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/iteration-slow-8                       271MB ± 0%     253MB ± 0%    -6.54%  (p=0.000 n=18+18)
LevelDBBatchSizes/goleveldb-100000-100-16-40/update-8                              46.7kB ± 6%    42.4kB ± 5%    -9.26%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-100-16-40/block-8                               5.82MB ± 9%    5.08MB ±11%   -12.75%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-no-in-tree-guarantee-fast-8       791B ± 0%      790B ± 0%    -0.13%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-no-in-tree-guarantee-slow-8     1.38kB ± 1%    1.77kB ± 1%   +27.92%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-hits-fast-8                      0.00B          0.00B           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-hits-slow-8                     1.97kB ± 1%    2.42kB ± 1%   +22.54%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/iteration-fast-8                      29.3MB ± 0%    29.3MB ± 0%      ~     (p=0.770 n=19+18)
LevelDBBatchSizes/goleveldb-100000-400-16-40/iteration-slow-8                       270MB ± 0%     254MB ± 0%    -6.27%  (p=0.000 n=18+19)
LevelDBBatchSizes/goleveldb-100000-400-16-40/update-8                              50.0kB ±11%    42.9kB ± 9%   -14.12%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-400-16-40/block-8                               24.7MB ± 8%    19.4MB ± 7%   -21.40%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-no-in-tree-guarantee-fast-8      790B ± 0%      790B ± 0%      ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-no-in-tree-guarantee-slow-8    1.37kB ± 1%    1.77kB ± 1%   +29.40%  (p=0.000 n=19+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-hits-fast-8                     0.00B          0.00B           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-hits-slow-8                    1.97kB ± 1%    2.42kB ± 1%   +22.66%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/iteration-fast-8                     29.3MB ± 0%    29.3MB ± 0%      ~     (p=0.931 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/iteration-slow-8                      270MB ± 0%     253MB ± 0%    -6.22%  (p=0.000 n=18+19)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/update-8                             47.9kB ±38%    39.8kB ±28%   -16.91%  (p=0.001 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/block-8                               137MB ± 7%      96MB ±10%   -29.83%  (p=0.000 n=17+20)

name                                                                             old allocs/op  new allocs/op  delta
Large/memdb-1000000-100-16-40/query-no-in-tree-guarantee-fast-8                      3.00 ± 0%      3.00 ± 0%      ~     (all equal)
Large/memdb-1000000-100-16-40/query-no-in-tree-guarantee-slow-8                      8.06 ±61%     36.19 ± 5%  +349.22%  (p=0.000 n=18+16)
Large/memdb-1000000-100-16-40/query-hits-fast-8                                      4.00 ± 0%      4.00 ± 0%      ~     (all equal)
Large/memdb-1000000-100-16-40/query-hits-slow-8                                      10.0 ± 0%      43.0 ± 0%  +330.00%  (p=0.000 n=20+20)
Large/memdb-1000000-100-16-40/iteration-fast-8                                      4.00M ± 0%     4.00M ± 0%      ~     (p=0.457 n=18+17)
Large/memdb-1000000-100-16-40/iteration-slow-8                                      14.0M ± 0%     33.0M ± 0%  +135.71%  (p=0.000 n=18+18)
Large/memdb-1000000-100-16-40/update-8                                                522 ± 3%       781 ± 2%   +49.72%  (p=0.000 n=17+19)
Large/memdb-1000000-100-16-40/block-8                                               53.3k ± 1%     78.0k ± 0%   +46.41%  (p=0.000 n=19+20)
Large/goleveldb-1000000-100-16-40/query-no-in-tree-guarantee-fast-8                  19.0 ± 0%      19.0 ± 0%      ~     (all equal)
Large/goleveldb-1000000-100-16-40/query-no-in-tree-guarantee-slow-8                  29.6 ±59%      56.0 ±38%   +88.99%  (p=0.000 n=19+19)
Large/goleveldb-1000000-100-16-40/query-hits-fast-8                                  19.0 ± 0%      19.0 ± 0%      ~     (all equal)
Large/goleveldb-1000000-100-16-40/query-hits-slow-8                                  35.6 ± 2%      64.4 ± 1%   +80.76%  (p=0.000 n=20+20)
Large/goleveldb-1000000-100-16-40/iteration-fast-8                                  5.31M ± 0%     5.31M ± 0%    +0.00%  (p=0.000 n=16+20)
Large/goleveldb-1000000-100-16-40/iteration-slow-8                                  48.2M ± 0%     57.2M ± 0%   +18.54%  (p=0.000 n=18+18)
Large/goleveldb-1000000-100-16-40/update-8                                            729 ± 8%       915 ± 7%   +25.57%  (p=0.000 n=19+19)
Large/goleveldb-1000000-100-16-40/block-8                                           85.9k ±12%     92.5k ± 7%    +7.72%  (p=0.000 n=20+20)
LevelDBLargeData/goleveldb-50000-100-32-100/query-no-in-tree-guarantee-fast-8        15.0 ± 0%      15.0 ± 0%      ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-100/query-no-in-tree-guarantee-slow-8        22.8 ± 3%      46.0 ± 0%  +102.20%  (p=0.000 n=40+33)
LevelDBLargeData/goleveldb-50000-100-32-100/query-hits-fast-8                        0.00           0.00           ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-100/query-hits-slow-8                        32.0 ± 0%      58.0 ± 0%   +81.25%  (p=0.000 n=40+36)
LevelDBLargeData/goleveldb-50000-100-32-100/iteration-fast-8                         274k ± 0%      274k ± 0%    +0.00%  (p=0.004 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-100/iteration-slow-8                        2.18M ± 0%     2.91M ± 0%   +33.39%  (p=0.000 n=39+37)
LevelDBLargeData/goleveldb-50000-100-32-100/update-8                                  468 ± 4%       656 ± 3%   +40.25%  (p=0.000 n=37+37)
LevelDBLargeData/goleveldb-50000-100-32-100/block-8                                 61.0k ±12%     75.6k ±11%   +23.84%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-no-in-tree-guarantee-fast-8       19.0 ± 0%      19.0 ± 0%      ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-no-in-tree-guarantee-slow-8       24.5 ± 2%      47.5 ± 1%   +93.67%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-hits-fast-8                       0.00           0.00           ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-1000/query-hits-slow-8                       35.0 ± 0%      61.0 ± 0%   +74.29%  (p=0.000 n=39+36)
LevelDBLargeData/goleveldb-50000-100-32-1000/iteration-fast-8                        438k ± 0%      438k ± 0%      ~     (p=0.404 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-1000/iteration-slow-8                       2.37M ± 0%     2.96M ± 0%   +24.95%  (p=0.000 n=38+38)
LevelDBLargeData/goleveldb-50000-100-32-1000/update-8                                 589 ± 7%       796 ± 5%   +35.32%  (p=0.000 n=37+38)
LevelDBLargeData/goleveldb-50000-100-32-1000/block-8                                76.5k ±11%     89.3k ± 9%   +16.80%  (p=0.000 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-no-in-tree-guarantee-fast-8      21.0 ± 0%      21.0 ± 0%      ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-no-in-tree-guarantee-slow-8      26.0 ± 0%      49.0 ± 0%   +88.46%  (p=0.000 n=40+31)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-hits-fast-8                      0.00           0.00           ~     (all equal)
LevelDBLargeData/goleveldb-50000-100-32-10000/query-hits-slow-8                      37.0 ± 0%      63.0 ± 0%   +70.27%  (p=0.000 n=40+33)
LevelDBLargeData/goleveldb-50000-100-32-10000/iteration-fast-8                       704k ± 0%      704k ± 0%    +0.00%  (p=0.028 n=40+40)
LevelDBLargeData/goleveldb-50000-100-32-10000/iteration-slow-8                      2.51M ± 0%     3.15M ± 0%   +25.46%  (p=0.000 n=38+38)
LevelDBLargeData/goleveldb-50000-100-32-10000/update-8                                765 ± 9%      1112 ± 4%   +45.28%  (p=0.000 n=39+34)
LevelDBLargeData/goleveldb-50000-100-32-10000/block-8                                108k ±11%      125k ± 8%   +15.11%  (p=0.000 n=39+33)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-no-in-tree-guarantee-fast-8         15.0 ± 0%      15.0 ± 0%      ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-no-in-tree-guarantee-slow-8         23.0 ± 0%      46.5 ± 1%  +102.39%  (p=0.000 n=18+20)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-hits-fast-8                         0.00           0.00           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-5-16-40/query-hits-slow-8                         33.0 ± 0%      59.0 ± 0%   +78.79%  (p=0.000 n=19+20)
LevelDBBatchSizes/goleveldb-100000-5-16-40/iteration-fast-8                          523k ± 0%      523k ± 0%      ~     (p=0.435 n=18+20)
LevelDBBatchSizes/goleveldb-100000-5-16-40/iteration-slow-8                         4.51M ± 0%     5.72M ± 0%   +26.92%  (p=0.000 n=16+18)
LevelDBBatchSizes/goleveldb-100000-5-16-40/update-8                                   694 ± 3%       862 ± 3%   +24.16%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-5-16-40/block-8                                  3.85k ± 5%     4.45k ± 3%   +15.62%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-no-in-tree-guarantee-fast-8        15.0 ± 0%      15.0 ± 0%      ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-no-in-tree-guarantee-slow-8        23.0 ± 0%      46.4 ± 1%  +101.52%  (p=0.000 n=19+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-hits-fast-8                        0.00           0.00           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-25-16-40/query-hits-slow-8                        33.0 ± 0%      59.0 ± 0%   +78.79%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-25-16-40/iteration-fast-8                         523k ± 0%      523k ± 0%      ~     (p=0.524 n=16+19)
LevelDBBatchSizes/goleveldb-100000-25-16-40/iteration-slow-8                        4.51M ± 0%     5.72M ± 0%   +26.87%  (p=0.000 n=18+18)
LevelDBBatchSizes/goleveldb-100000-25-16-40/update-8                                  565 ± 5%       730 ± 2%   +29.23%  (p=0.000 n=20+18)
LevelDBBatchSizes/goleveldb-100000-25-16-40/block-8                                 16.5k ± 4%     19.9k ± 7%   +20.67%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-no-in-tree-guarantee-fast-8       15.0 ± 0%      15.0 ± 0%      ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-no-in-tree-guarantee-slow-8       23.0 ± 0%      46.5 ± 1%  +101.96%  (p=0.000 n=19+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-hits-fast-8                       0.00           0.00           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-100-16-40/query-hits-slow-8                       33.0 ± 0%      59.0 ± 0%   +78.79%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/iteration-fast-8                        523k ± 0%      523k ± 0%    -0.00%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-100-16-40/iteration-slow-8                       4.51M ± 0%     5.72M ± 0%   +26.89%  (p=0.000 n=18+18)
LevelDBBatchSizes/goleveldb-100000-100-16-40/update-8                                 508 ± 5%       680 ± 3%   +33.85%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-100-16-40/block-8                                61.9k ± 8%     76.0k ± 7%   +22.66%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-no-in-tree-guarantee-fast-8       15.0 ± 0%      15.0 ± 0%      ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-no-in-tree-guarantee-slow-8       23.2 ± 3%      46.4 ± 1%   +99.78%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-hits-fast-8                       0.00           0.00           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-400-16-40/query-hits-slow-8                       33.0 ± 0%      59.0 ± 0%   +78.79%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/iteration-fast-8                        523k ± 0%      523k ± 0%      ~     (p=0.286 n=20+20)
LevelDBBatchSizes/goleveldb-100000-400-16-40/iteration-slow-8                       4.51M ± 0%     5.72M ± 0%   +26.92%  (p=0.000 n=18+18)
LevelDBBatchSizes/goleveldb-100000-400-16-40/update-8                                 495 ±17%       647 ±10%   +30.75%  (p=0.000 n=19+19)
LevelDBBatchSizes/goleveldb-100000-400-16-40/block-8                                 251k ± 8%      285k ± 6%   +13.47%  (p=0.000 n=19+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-no-in-tree-guarantee-fast-8      15.0 ± 0%      15.0 ± 0%      ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-no-in-tree-guarantee-slow-8      23.0 ± 0%      46.5 ± 1%  +102.17%  (p=0.000 n=19+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-hits-fast-8                      0.00           0.00           ~     (all equal)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/query-hits-slow-8                      33.0 ± 0%      59.0 ± 0%   +78.79%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/iteration-fast-8                       523k ± 0%      523k ± 0%    +0.00%  (p=0.029 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/iteration-slow-8                      4.51M ± 0%     5.72M ± 0%   +26.91%  (p=0.000 n=18+18)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/update-8                                393 ±40%       486 ±28%   +23.72%  (p=0.000 n=20+20)
LevelDBBatchSizes/goleveldb-100000-2000-16-40/block-8                               1.24M ±12%     1.27M ±11%      ~     (p=0.565 n=20+20)

mutable_tree.go Outdated
// save new nodes
if tree.root != nil {
// ensure init the nonce
tree.nonce = 0
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems tree.nonce could be a local var?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah, it sounds good!

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Nov 25, 2022

This pull request fixes 1 alert when merging b7d631b into 7204160 - view on LGTM.com

fixed alerts:

  • 1 for Unreachable statement

Heads-up: LGTM.com's PR analysis will be disabled on the 5th of December, and LGTM.com will be shut down ⏻ completely on the 16th of December 2022. It looks like GitHub code scanning with CodeQL is already set up for this repo, so no further action is needed 🚀. For more information, please check out our post on the GitHub blog.

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Nov 25, 2022

This pull request fixes 1 alert when merging 6d95cfb into 7204160 - view on LGTM.com

fixed alerts:

  • 1 for Unreachable statement

Heads-up: LGTM.com's PR analysis will be disabled on the 5th of December, and LGTM.com will be shut down ⏻ completely on the 16th of December 2022. It looks like GitHub code scanning with CodeQL is already set up for this repo, so no further action is needed 🚀. For more information, please check out our post on the GitHub blog.

Copy link
Member

@p0mvn p0mvn left a comment

Choose a reason for hiding this comment

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

The nonce idea starting to make sense.

From the ADR, it seemed that nonces are assigned as we are building up a tree during set(). In that case, nonces would not follow lexicographic order, leading to superfluous merging and compactions overhead.

Since nonces are assigned retroactively during SaveVersion, that could work. However, currently, it seems to be broken due to pre-order traversal when assigning nonces.

I think that if we change pre-order traversal to in-order, the performance would significantly improve. Now, the lexicographic order would be followed. I would love to see the updated benchmarks with this change applied.

Additionally, I do not understand why we need to retrieve all nodes into a map with tree.getNewNodes() in SaveVersion(). We should simply do another in-order tree traversal to save the nodes.

Lastly, I'm not following the partial removal of orphans. I saw the comment: #597 (comment) about having plans to remove them. However, here it seems to have been done in part. I think we should either remove them completely or fully keep them in this PR. Partial removal doesn't seem to make a lot of sense and might interfere with benchmarks.

nodedb.go Outdated
if len(hash) == 0 {
return nil, ErrNodeMissingHash
if nk == nil {
return nil, nil
Copy link
Member

Choose a reason for hiding this comment

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

Why are we returning nil, nil and not nil, err here?

Copy link
Member

Choose a reason for hiding this comment

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

We should probably return ErrNodeMissingNodeKey like in SaveNode and cover this branch with a test

logger.Debug("BATCH SAVE %X %p\n", node.hash, node)
node.persisted = true

// resetBatch only working on generate a genesis block
Copy link
Member

Choose a reason for hiding this comment

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

What does it mean? Can you elaborate? Why do we even need this part of the code?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this comes from the old function nodedb.SaveBranch, tbh I am not sure about this usecase.

func (tree *MutableTree) balance(node *Node, orphans *[]*Node) (newSelf *Node, err error) {
if node.persisted {
func (tree *MutableTree) balance(node *Node) (newSelf *Node, err error) {
if node.nodeKey != nil {
Copy link
Member

Choose a reason for hiding this comment

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

We should have a check for node itself not being nil and cover with a test

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

balance always comes after clone(), it ensures node is not nil

}

lftBalance, err := leftNode.calcBalance(tree.ImmutableTree)
lftBalance, err := node.leftNode.calcBalance(tree.ImmutableTree)
Copy link
Member

Choose a reason for hiding this comment

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

What if node.leftNode is nil?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

same reason( call balance after clone()) , it makes sure node has children

if err != nil {
return nil, err
}

if lftBalance >= 0 {
// Left Left Case
newNode, orphaned, err := tree.rotateRight(node)
Copy link
Member

Choose a reason for hiding this comment

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

Why do we still have orphans as a field and track them in some other parts of the code but not here?

mutable_tree.go Outdated

// save new nodes
if tree.root != nil {
newNodes, err := tree.getNewNodes()
Copy link
Member

Choose a reason for hiding this comment

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

Why do we have to get all these nodes in memory and then iterate them as a map a second time only to save?

After we iterate to assign nonces, there must be another in-order tree iteration to make sure that we save nodes in lexicographic order.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the purpose of in-order is to calculate the node hash and then to make sure of lexicographic order, it stores all nodes in the map and iterates again in the sort order of nonce. I think we can't do both hash calc and nonce assigning.
The other purpose is I'd like to keep the nonce of the root as 1, and keep the ASC order of nodes when visiting the leaf node.

Copy link
Member

Choose a reason for hiding this comment

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

What if we do this?

	recursiveSpread = func(node *Node) (*NodeKey, error) {
		if node.nodeKey != nil {
			return node.nodeKey, nil
		}

		var err error
		if node.leftNode != nil {
			node.leftNodeKey, err = recursiveSpread(node.leftNode)
			if err != nil {
				return nil, err
			}
		}

		nonce++
		node.nodeKey = &NodeKey{
			version: version,
			nonce:   nonce,
		}

		if node.rightNode != nil {
			node.rightNodeKey, err = recursiveSpread(node.rightNode)
			if err != nil {
				return nil, err
			}
		}

		_, err = node._hash(version)
		if err != nil {
			return nil, err
		}

		node.leftNode = nil
		node.rightNode = nil
		newNodes[node.nodeKey.nonce] = node
		return node.nodeKey, nil
	}

This way, the nonce assignment follows in-order traversal while hashing follows post-order traversal as desired.

Copy link
Member

@p0mvn p0mvn Nov 28, 2022

Choose a reason for hiding this comment

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

Then, we can do a second in-order traversal of the tree to write the nodes to disk, removing the need for the map

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the second traversal makes sense, but I think the second traversal should be pre-order.

Comment on lines +1182 to +1186
nonce++
node.nodeKey = &NodeKey{
version: version,
nonce: nonce,
}
Copy link
Member

Choose a reason for hiding this comment

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

This is a pre-order traversal. As a result, the nonces do not follow the lexicographic order. This leads to increased superfluous merges.

Please try changing to in-order traversal. I would expect the benchmarks to improve with that change

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

you are right, this is why we use the map and iterate again.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am not sure why in-order is essential here, we are using the node key as version | nonce. it doesn't matter the order of the key. I think we have to focus on the tree iterate rather than it.

@lgtm-com
Copy link
Contributor

lgtm-com bot commented Nov 29, 2022

This pull request fixes 1 alert when merging dcc0d07 into 7204160 - view on LGTM.com

fixed alerts:

  • 1 for Unreachable statement

Heads-up: LGTM.com's PR analysis will be disabled on the 5th of December, and LGTM.com will be shut down ⏻ completely on the 16th of December 2022. It looks like GitHub code scanning with CodeQL is already set up for this repo, so no further action is needed 🚀. For more information, please check out our post on the GitHub blog.

@cool-develope cool-develope requested review from yihuang and p0mvn and removed request for yihuang November 29, 2022 15:40
@lgtm-com
Copy link
Contributor

lgtm-com bot commented Nov 29, 2022

This pull request fixes 1 alert when merging 03baaf5 into 7204160 - view on LGTM.com

fixed alerts:

  • 1 for Unreachable statement

Heads-up: LGTM.com's PR analysis will be disabled on the 5th of December, and LGTM.com will be shut down ⏻ completely on the 16th of December 2022. It looks like GitHub code scanning with CodeQL is already set up for this repo, so no further action is needed 🚀. For more information, please check out our post on the GitHub blog.

@tac0turtle
Copy link
Member

closing this in favour of the #650

@tac0turtle tac0turtle closed this Jan 2, 2023
@tac0turtle tac0turtle deleted the 592/subtask-2 branch April 11, 2023 09:44
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.

5 participants