-
Notifications
You must be signed in to change notification settings - Fork 269
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: implement the lazy_set
feature
#750
Changes from 6 commits
142f734
2f68a9b
bd015a1
97ad970
9539474
fb41313
7bf4ef7
99b4c14
3de52d8
2bc0903
3d4542a
4a1cfee
6671c4d
8b868ec
dc14192
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# DBGenerator | ||
|
||
`dbgenerator` is a command line tool to generate a `iavl` tree based on the legacy format of the node key. | ||
This tool is used for testing the `lazy loading and set` feature of the `iavl` tree. | ||
|
||
## Usage | ||
|
||
It takes 4 arguments: | ||
- dbtype: the type of database to use. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe, the purpose of this tool is to generate the legacy tree, it can be used in benchmarking and |
||
- dbdir: the directory to store the database. | ||
- `random` or `sequential`: The `sequential` option will generate the tree from `1` to `version` in order. The `random` option will remove half of the versions randomly from the `sequential` mode. | ||
cool-develope marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- version: the number of versions to generate. | ||
cool-develope marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```shell | ||
go run main.go <dbtype> <dbdir> <random|sequential> <version> | ||
cool-develope marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
module dbgenerator | ||
cool-develope marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
go 1.20 | ||
|
||
require ( | ||
github.com/cometbft/cometbft-db v0.7.0 | ||
github.com/cosmos/iavl v0.20.0 | ||
) | ||
|
||
require ( | ||
github.com/cespare/xxhash v1.1.0 // indirect | ||
github.com/confio/ics23/go v0.9.0 // indirect | ||
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect | ||
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect | ||
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect | ||
github.com/dustin/go-humanize v1.0.0 // indirect | ||
github.com/gogo/protobuf v1.3.2 // indirect | ||
github.com/golang/protobuf v1.5.2 // indirect | ||
github.com/golang/snappy v0.0.4 // indirect | ||
github.com/google/btree v1.1.2 // indirect | ||
github.com/jmhodges/levigo v1.0.0 // indirect | ||
github.com/klauspost/compress v1.15.9 // indirect | ||
github.com/pkg/errors v0.9.1 // indirect | ||
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect | ||
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect | ||
go.etcd.io/bbolt v1.3.6 // indirect | ||
golang.org/x/crypto v0.4.0 // indirect | ||
golang.org/x/net v0.4.0 // indirect | ||
golang.org/x/sys v0.6.0 // indirect | ||
google.golang.org/protobuf v1.28.1 // indirect | ||
) |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"math/rand" | ||
"os" | ||
"path/filepath" | ||
"strconv" | ||
|
||
dbm "github.com/cometbft/cometbft-db" | ||
"github.com/cosmos/iavl" | ||
) | ||
|
||
const ( | ||
DefaultCacheSize = 1000 | ||
) | ||
|
||
func main() { | ||
args := os.Args[1:] | ||
if len(args) < 4 { | ||
fmt.Fprintln(os.Stderr, "Usage: dbgenerator <dbtype> <dbdir> <random|sequential> <version>") | ||
tac0turtle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
os.Exit(1) | ||
} | ||
|
||
version, err := strconv.Atoi(args[3]) | ||
if err != nil { | ||
fmt.Fprintf(os.Stderr, "Invalid version number: %s\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
if err = generateTree(args[0], args[1], args[2], version); err != nil { | ||
fmt.Fprintf(os.Stderr, "Error generating tree: %s\n", err) | ||
} | ||
} | ||
|
||
func openDB(dbType, dbDir string) (dbm.DB, error) { | ||
dir, err := filepath.Abs(dbDir) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
db, err := dbm.NewDB("test", dbm.BackendType(dbType), dir) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return db, nil | ||
} | ||
|
||
func generateTree(dbType, dbDir, mode string, version int) error { | ||
db, err := openDB(dbType, dbDir) | ||
if err != nil { | ||
return err | ||
} | ||
defer db.Close() | ||
|
||
switch mode { | ||
case "random": | ||
return generateRandomTree(db, version) | ||
case "sequential": | ||
_, err = generateSequentialTree(db, version) | ||
return err | ||
default: | ||
return fmt.Errorf("invalid mode: %s", mode) | ||
} | ||
} | ||
|
||
func generateRandomTree(db dbm.DB, version int) error { | ||
t, err := generateSequentialTree(db, version) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// delete the half of the versions | ||
versions := make([]int64, version) | ||
for i := 0; i < version; i++ { | ||
versions[i] = int64(i + 1) | ||
} | ||
|
||
// make sure the latest version is not deleted | ||
for i := 1; i <= version/2; i++ { | ||
index := rand.Intn(version - i) | ||
if err := t.DeleteVersion(versions[index]); err != nil { | ||
return err | ||
} | ||
versions[index], versions[version-i-1] = versions[version-i-1], versions[index] | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func generateSequentialTree(db dbm.DB, version int) (*iavl.MutableTree, error) { | ||
t, err := iavl.NewMutableTreeWithOpts(db, DefaultCacheSize, nil, false) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
for i := 0; i < version; i++ { | ||
leafCount := rand.Int31n(50) | ||
for j := int32(0); j < leafCount; j++ { | ||
t.Set(randBytes(32), randBytes(32)) | ||
} | ||
if _, _, err = t.SaveVersion(); err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return t, err | ||
} | ||
|
||
func randBytes(length int) []byte { | ||
key := make([]byte, length) | ||
// math.rand.Read always returns err=nil | ||
// we do not need cryptographic randomness for this test: | ||
rand.Read(key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we are using math/rand in generating random integers There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, what I meant was that |
||
return key | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,7 +21,7 @@ type KVPairReceiver func(pair *KVPair) error | |
// | ||
// The algorithm don't run in constant memory strictly, but it tried the best the only | ||
// keep minimal intermediate states in memory. | ||
func (ndb *nodeDB) extractStateChanges(prevVersion int64, prevRoot *NodeKey, root *NodeKey, receiver KVPairReceiver) error { | ||
func (ndb *nodeDB) extractStateChanges(prevVersion int64, prevRoot, root []byte, receiver KVPairReceiver) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a big fan of this change in particular. Actually it's what I originally recommended. #676 (review) |
||
curIter, err := NewNodeIterator(root, ndb) | ||
if err != nil { | ||
return err | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dbgenerator
is a pretty generic name for its seemingly specialized purpose. How aboutdumplegacy
? I assume the legacy format will be phased out over time.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that
dumplegacy
is a more descriptive name for this special purpose tool.