Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
66826aa4
Commit
66826aa4
authored
Jan 23, 2019
by
liuyuhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add test
parent
db64ffcb
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
14 additions
and
2059 deletions
+14
-2059
kvmvccMavl.go
plugin/store/kvmvccMavl/kvmvccMavl.go
+12
-31
kvmvccdb.go
plugin/store/kvmvccMavl/kvmvccdb.go
+2
-4
kvmvccdb_test.go
plugin/store/kvmvccMavl/kvmvccdb_test.go
+0
-1009
mavl_test.go
plugin/store/kvmvccMavl/mavl_test.go
+0
-1015
No files found.
plugin/store/kvmvccMavl/kvmvccMavl.go
View file @
66826aa4
...
...
@@ -10,10 +10,7 @@ import (
"github.com/33cn/chain33/queue"
drivers
"github.com/33cn/chain33/system/store"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/system/store/mavl"
"github.com/33cn/plugin/plugin/store/kvmvcc"
"github.com/hashicorp/golang-lru"
"encoding/json"
"errors"
)
...
...
@@ -41,8 +38,8 @@ func init() {
// KVMVCCMavlStore provide kvmvcc and mavl store interface implementation
type
KVMVCCMavlStore
struct
{
*
drivers
.
BaseStore
*
kvmvccdb
.
KVMVCCStore
*
mavl
.
Store
*
KVMVCCStore
*
Mavl
Store
cance
*
lru
.
Cache
}
...
...
@@ -81,29 +78,13 @@ func New(cfg *types.Store, sub []byte) queue.Module {
subMavlcfg
.
EnableMavlPrune
=
subcfg
.
EnableMavlPrune
subMavlcfg
.
PruneHeight
=
subcfg
.
PruneHeight
}
mvcVal
,
_
:=
json
.
Marshal
(
&
subKVMVCCcfg
)
mavlVal
,
_
:=
json
.
Marshal
(
&
subMavlcfg
)
cance
,
err
:=
lru
.
New
(
1024
)
if
err
!=
nil
{
panic
(
"new KVMVCCMavlStore fail"
)
}
mvccCfg
:=
&
types
.
Store
{}
mvccCfg
.
Name
=
"kvmvcc"
mvccCfg
.
Driver
=
cfg
.
Driver
mvccCfg
.
DbPath
=
cfg
.
DbPath
+
"/kvmvcc"
mvccCfg
.
DbCache
=
cfg
.
DbCache
mvccCfg
.
LocalDBVersion
=
cfg
.
LocalDBVersion
mavlCfg
:=
&
types
.
Store
{}
mavlCfg
.
Name
=
"mavl"
mavlCfg
.
Driver
=
cfg
.
Driver
mavlCfg
.
DbPath
=
cfg
.
DbPath
+
"/mavl"
mavlCfg
.
DbCache
=
cfg
.
DbCache
mavlCfg
.
LocalDBVersion
=
cfg
.
LocalDBVersion
kvms
=
&
KVMVCCMavlStore
{
bs
,
kvmvccdb
.
New
(
mvccCfg
,
mvcVal
)
.
(
*
kvmvccdb
.
KVMVCCStore
),
mavl
.
New
(
mavlCfg
,
mavlVal
)
.
(
*
mavl
.
Store
),
cance
}
kvms
=
&
KVMVCCMavlStore
{
bs
,
NewKVMVCC
(
cfg
,
&
subKVMVCCcfg
,
bs
.
GetDB
()),
NewMavl
(
cfg
,
&
subMavlcfg
,
bs
.
GetDB
()),
cance
}
bs
.
SetChild
(
kvms
)
return
kvms
}
...
...
@@ -112,7 +93,7 @@ func New(cfg *types.Store, sub []byte) queue.Module {
func
(
kvmMavls
*
KVMVCCMavlStore
)
Close
()
{
kvmMavls
.
BaseStore
.
Close
()
kvmMavls
.
KVMVCCStore
.
Close
()
kvmMavls
.
Store
.
Close
()
kvmMavls
.
Mavl
Store
.
Close
()
kmlog
.
Info
(
"store kvdb closed"
)
}
...
...
@@ -120,7 +101,7 @@ func (kvmMavls *KVMVCCMavlStore) Close() {
func
(
kvmMavls
*
KVMVCCMavlStore
)
Set
(
datas
*
types
.
StoreSet
,
sync
bool
)
([]
byte
,
error
)
{
// 这里后续需要考虑分叉回退
if
datas
.
Height
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
Store
.
Set
(
datas
,
sync
)
hash
,
err
:=
kvmMavls
.
Mavl
Store
.
Set
(
datas
,
sync
)
if
err
!=
nil
{
return
hash
,
err
}
...
...
@@ -145,7 +126,7 @@ func (kvmMavls *KVMVCCMavlStore) Set(datas *types.StoreSet, sync bool) ([]byte,
func
(
kvmMavls
*
KVMVCCMavlStore
)
Get
(
datas
*
types
.
StoreGet
)
[][]
byte
{
if
value
,
ok
:=
kvmMavls
.
cance
.
Get
(
string
(
datas
.
StateHash
));
ok
{
if
value
.
(
int64
)
<
kvmvccMavlFork
{
return
kvmMavls
.
Store
.
Get
(
datas
)
return
kvmMavls
.
Mavl
Store
.
Get
(
datas
)
}
return
kvmMavls
.
KVMVCCStore
.
Get
(
datas
)
}
...
...
@@ -156,7 +137,7 @@ func (kvmMavls *KVMVCCMavlStore) Get(datas *types.StoreGet) [][]byte {
func
(
kvmMavls
*
KVMVCCMavlStore
)
MemSet
(
datas
*
types
.
StoreSet
,
sync
bool
)
([]
byte
,
error
)
{
// 这里后续需要考虑分叉回退
if
datas
.
Height
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
Store
.
MemSet
(
datas
,
sync
)
hash
,
err
:=
kvmMavls
.
Mavl
Store
.
MemSet
(
datas
,
sync
)
if
err
!=
nil
{
return
hash
,
err
}
...
...
@@ -181,7 +162,7 @@ func (kvmMavls *KVMVCCMavlStore) MemSet(datas *types.StoreSet, sync bool) ([]byt
func
(
kvmMavls
*
KVMVCCMavlStore
)
Commit
(
req
*
types
.
ReqHash
)
([]
byte
,
error
)
{
if
value
,
ok
:=
kvmMavls
.
cance
.
Get
(
string
(
req
.
Hash
));
ok
{
if
value
.
(
int64
)
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
Store
.
Commit
(
req
)
hash
,
err
:=
kvmMavls
.
Mavl
Store
.
Commit
(
req
)
if
err
!=
nil
{
return
hash
,
err
}
...
...
@@ -200,7 +181,7 @@ func (kvmMavls *KVMVCCMavlStore) Commit(req *types.ReqHash) ([]byte, error) {
func
(
kvmMavls
*
KVMVCCMavlStore
)
Rollback
(
req
*
types
.
ReqHash
)
([]
byte
,
error
)
{
if
value
,
ok
:=
kvmMavls
.
cance
.
Get
(
string
(
req
.
Hash
));
ok
{
if
value
.
(
int64
)
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
Store
.
Rollback
(
req
)
hash
,
err
:=
kvmMavls
.
Mavl
Store
.
Rollback
(
req
)
if
err
!=
nil
{
return
hash
,
err
}
...
...
@@ -219,7 +200,7 @@ func (kvmMavls *KVMVCCMavlStore) Rollback(req *types.ReqHash) ([]byte, error) {
func
(
kvmMavls
*
KVMVCCMavlStore
)
IterateRangeByStateHash
(
statehash
[]
byte
,
start
[]
byte
,
end
[]
byte
,
ascending
bool
,
fn
func
(
key
,
value
[]
byte
)
bool
)
{
if
value
,
ok
:=
kvmMavls
.
cance
.
Get
(
string
(
statehash
));
ok
{
if
value
.
(
int64
)
<
kvmvccMavlFork
{
kvmMavls
.
Store
.
IterateRangeByStateHash
(
statehash
,
start
,
end
,
ascending
,
fn
)
kvmMavls
.
Mavl
Store
.
IterateRangeByStateHash
(
statehash
,
start
,
end
,
ascending
,
fn
)
}
kvmMavls
.
KVMVCCStore
.
IterateRangeByStateHash
(
statehash
,
start
,
end
,
ascending
,
fn
)
}
...
...
@@ -235,7 +216,7 @@ func (kvmMavls *KVMVCCMavlStore) ProcEvent(msg queue.Message) {
func
(
kvmMavls
*
KVMVCCMavlStore
)
Del
(
req
*
types
.
StoreDel
)
([]
byte
,
error
)
{
// 这里后续需要考虑分叉回退
if
req
.
Height
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
Store
.
Del
(
req
)
hash
,
err
:=
kvmMavls
.
Mavl
Store
.
Del
(
req
)
if
err
!=
nil
{
return
hash
,
err
}
...
...
plugin/store/kvmvccMavl/kvmvccdb.go
View file @
66826aa4
...
...
@@ -8,7 +8,6 @@ import (
"github.com/33cn/chain33/common"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/queue"
drivers
"github.com/33cn/chain33/system/store"
"github.com/33cn/chain33/types"
"github.com/golang/protobuf/proto"
)
...
...
@@ -28,16 +27,15 @@ type KVMVCCStore struct {
// NewKVMVCC construct KVMVCCStore module
func
NewKVMVCC
(
cfg
*
types
.
Store
,
sub
*
subKVMVCCConfig
,
db
dbm
.
DB
)
*
KVMVCCStore
{
bs
:=
drivers
.
NewBaseStore
(
cfg
)
var
kvs
*
KVMVCCStore
enable
:=
false
if
sub
!=
nil
{
enable
=
sub
.
EnableMVCCIter
}
if
enable
{
kvs
=
&
KVMVCCStore
{
db
,
dbm
.
NewMVCCIter
(
bs
.
GetDB
()
),
make
(
map
[
string
][]
*
types
.
KeyValue
),
true
}
kvs
=
&
KVMVCCStore
{
db
,
dbm
.
NewMVCCIter
(
db
),
make
(
map
[
string
][]
*
types
.
KeyValue
),
true
}
}
else
{
kvs
=
&
KVMVCCStore
{
db
,
dbm
.
NewMVCC
(
bs
.
GetDB
()
),
make
(
map
[
string
][]
*
types
.
KeyValue
),
false
}
kvs
=
&
KVMVCCStore
{
db
,
dbm
.
NewMVCC
(
db
),
make
(
map
[
string
][]
*
types
.
KeyValue
),
false
}
}
return
kvs
}
...
...
plugin/store/kvmvccMavl/kvmvccdb_test.go
deleted
100644 → 0
View file @
db64ffcb
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
kvmvccMavl
import
(
"encoding/json"
"io/ioutil"
"os"
"testing"
"time"
"fmt"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common"
drivers
"github.com/33cn/chain33/system/store"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
)
const
MaxKeylenth
int
=
64
func
newStoreCfg
(
dir
string
)
*
types
.
Store
{
return
&
types
.
Store
{
Name
:
"kvmvcc_test"
,
Driver
:
"leveldb"
,
DbPath
:
dir
,
DbCache
:
100
}
}
func
newStoreCfgIter
(
dir
string
)
(
*
types
.
Store
,
[]
byte
)
{
return
&
types
.
Store
{
Name
:
"kvmvcc_test"
,
Driver
:
"leveldb"
,
DbPath
:
dir
,
DbCache
:
100
},
enableConfig
()
}
func
TestKvmvccdbNewClose
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
t
,
store
)
store
.
Close
()
}
func
TestKvmvccdbSetGet
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
t
,
store
)
keys0
:=
[][]
byte
{[]
byte
(
"mk1"
),
[]
byte
(
"mk2"
)}
get0
:=
&
types
.
StoreGet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
Keys
:
keys0
}
values0
:=
store
.
Get
(
get0
)
//klog.Info("info", "info", values0)
// Get exist key, result nil
assert
.
Len
(
t
,
values0
,
2
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
values0
[
0
])
assert
.
Equal
(
t
,
[]
byte
(
nil
),
values0
[
1
])
var
kv
[]
*
types
.
KeyValue
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"k1"
),
Value
:
[]
byte
(
"v1"
)})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"k2"
),
Value
:
[]
byte
(
"v2"
)})
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
hash
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
keys
:=
[][]
byte
{[]
byte
(
"k1"
),
[]
byte
(
"k2"
)}
get1
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values
:=
store
.
Get
(
get1
)
assert
.
Len
(
t
,
values
,
2
)
assert
.
Equal
(
t
,
[]
byte
(
"v1"
),
values
[
0
])
assert
.
Equal
(
t
,
[]
byte
(
"v2"
),
values
[
1
])
keys
=
[][]
byte
{[]
byte
(
"k1"
)}
get2
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values2
:=
store
.
Get
(
get2
)
assert
.
Len
(
t
,
values2
,
1
)
assert
.
Equal
(
t
,
[]
byte
(
"v1"
),
values2
[
0
])
get3
:=
&
types
.
StoreGet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
Keys
:
keys
}
values3
:=
store
.
Get
(
get3
)
assert
.
Len
(
t
,
values3
,
1
)
}
func
TestKvmvccdbMemSet
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
t
,
store
)
var
kv
[]
*
types
.
KeyValue
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk1"
),
Value
:
[]
byte
(
"v1"
)})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk2"
),
Value
:
[]
byte
(
"v2"
)})
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
keys
:=
[][]
byte
{[]
byte
(
"mk1"
),
[]
byte
(
"mk2"
)}
get1
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values
:=
store
.
Get
(
get1
)
assert
.
Len
(
t
,
values
,
2
)
assert
.
Nil
(
t
,
values
[
0
])
assert
.
Nil
(
t
,
values
[
1
])
actHash
,
_
:=
store
.
Commit
(
&
types
.
ReqHash
{
Hash
:
hash
})
assert
.
Equal
(
t
,
hash
,
actHash
)
notExistHash
,
_
:=
store
.
Commit
(
&
types
.
ReqHash
{
Hash
:
drivers
.
EmptyRoot
[
:
]})
assert
.
Nil
(
t
,
notExistHash
)
values
=
store
.
Get
(
get1
)
assert
.
Len
(
t
,
values
,
2
)
assert
.
Equal
(
t
,
values
[
0
],
kv
[
0
]
.
Value
)
assert
.
Equal
(
t
,
values
[
1
],
kv
[
1
]
.
Value
)
}
func
TestKvmvccdbRollback
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
t
,
store
)
var
kv
[]
*
types
.
KeyValue
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk1"
),
Value
:
[]
byte
(
"v1"
)})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk2"
),
Value
:
[]
byte
(
"v2"
)})
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
keys
:=
[][]
byte
{[]
byte
(
"mk1"
),
[]
byte
(
"mk2"
)}
get1
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values
:=
store
.
Get
(
get1
)
assert
.
Len
(
t
,
values
,
2
)
assert
.
Nil
(
t
,
values
[
0
])
assert
.
Nil
(
t
,
values
[
1
])
actHash
,
_
:=
store
.
Rollback
(
&
types
.
ReqHash
{
Hash
:
hash
})
assert
.
Equal
(
t
,
hash
,
actHash
)
notExistHash
,
err
:=
store
.
Rollback
(
&
types
.
ReqHash
{
Hash
:
drivers
.
EmptyRoot
[
:
]})
assert
.
Nil
(
t
,
notExistHash
)
assert
.
Equal
(
t
,
types
.
ErrHashNotFound
.
Error
(),
err
.
Error
())
}
func
TestKvmvccdbRollbackBatch
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
t
,
store
)
var
kv
[]
*
types
.
KeyValue
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk1"
),
Value
:
[]
byte
(
"v1"
)})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk2"
),
Value
:
[]
byte
(
"v2"
)})
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
var
kvset
[]
*
types
.
KeyValue
req
:=
&
types
.
ReqHash
{
Hash
:
hash
}
hash1
:=
make
([]
byte
,
len
(
hash
))
copy
(
hash1
,
hash
)
store
.
Commit
(
req
)
for
i
:=
1
;
i
<=
202
;
i
++
{
kvset
=
nil
datas1
:=
&
types
.
StoreSet
{
StateHash
:
hash1
,
KV
:
datas
.
KV
,
Height
:
datas
.
Height
+
int64
(
i
)}
s1
:=
fmt
.
Sprintf
(
"v1-%03d"
,
datas
.
Height
+
int64
(
i
))
s2
:=
fmt
.
Sprintf
(
"v2-%03d"
,
datas
.
Height
+
int64
(
i
))
datas
.
KV
[
0
]
.
Value
=
[]
byte
(
s1
)
datas
.
KV
[
1
]
.
Value
=
[]
byte
(
s2
)
hash1
=
calcHash
(
datas1
)
//zzh
//klog.Debug("KVMVCCStore MemSet AddMVCC", "prestatehash", common.ToHex(datas.StateHash), "hash", common.ToHex(hash), "height", datas.Height)
klog
.
Info
(
"KVMVCCStore MemSet AddMVCC for 202"
,
"prestatehash"
,
common
.
ToHex
(
datas1
.
StateHash
),
"hash"
,
common
.
ToHex
(
hash1
),
"height"
,
datas1
.
Height
)
kvlist
,
err
:=
store
.
mvcc
.
AddMVCC
(
datas1
.
KV
,
hash1
,
datas1
.
StateHash
,
datas1
.
Height
)
if
err
!=
nil
{
klog
.
Info
(
"KVMVCCStore MemSet AddMVCC failed for 202, continue"
)
continue
}
if
len
(
kvlist
)
>
0
{
kvset
=
append
(
kvset
,
kvlist
...
)
}
store
.
kvsetmap
[
string
(
hash1
)]
=
kvset
req
:=
&
types
.
ReqHash
{
Hash
:
hash1
}
store
.
Commit
(
req
)
}
maxVersion
,
err
:=
store
.
mvcc
.
GetMaxVersion
()
assert
.
Equal
(
t
,
err
,
nil
)
assert
.
Equal
(
t
,
int64
(
202
),
maxVersion
)
keys
:=
[][]
byte
{[]
byte
(
"mk1"
),
[]
byte
(
"mk2"
)}
get1
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values
:=
store
.
Get
(
get1
)
assert
.
Len
(
t
,
values
,
2
)
assert
.
Equal
(
t
,
[]
byte
(
"v1"
),
values
[
0
])
assert
.
Equal
(
t
,
[]
byte
(
"v2"
),
values
[
1
])
var
kv2
[]
*
types
.
KeyValue
kv2
=
append
(
kv2
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk1"
),
Value
:
[]
byte
(
"v11"
)})
kv2
=
append
(
kv2
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk2"
),
Value
:
[]
byte
(
"v22"
)})
//触发批量回滚
datas2
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv2
,
Height
:
1
}
hash
,
err
=
store
.
MemSet
(
datas2
,
true
)
assert
.
Nil
(
t
,
err
)
req
=
&
types
.
ReqHash
{
Hash
:
hash
}
store
.
Commit
(
req
)
maxVersion
,
err
=
store
.
mvcc
.
GetMaxVersion
()
assert
.
Equal
(
t
,
nil
,
err
)
assert
.
Equal
(
t
,
int64
(
3
),
maxVersion
)
get2
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values2
:=
store
.
Get
(
get2
)
assert
.
Len
(
t
,
values
,
2
)
assert
.
Equal
(
t
,
values2
[
0
],
kv2
[
0
]
.
Value
)
assert
.
Equal
(
t
,
values2
[
1
],
kv2
[
1
]
.
Value
)
datas3
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv2
,
Height
:
2
}
hash
,
err
=
store
.
MemSet
(
datas3
,
true
)
assert
.
Nil
(
t
,
err
)
req
=
&
types
.
ReqHash
{
Hash
:
hash
}
store
.
Commit
(
req
)
maxVersion
,
err
=
store
.
mvcc
.
GetMaxVersion
()
assert
.
Equal
(
t
,
nil
,
err
)
assert
.
Equal
(
t
,
int64
(
2
),
maxVersion
)
}
func
enableConfig
()
[]
byte
{
data
,
_
:=
json
.
Marshal
(
&
subConfig
{
EnableMVCCIter
:
true
})
return
data
}
func
TestIterateRangeByStateHash
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
storeCfg
,
sub
:=
newStoreCfgIter
(
dir
)
store
:=
New
(
storeCfg
,
sub
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
t
,
store
)
execaddr
:=
"0111vcBNSEA7fZhAdLJphDwQRQJa111"
addr
:=
"06htvcBNSEA7fZhAdLJphDwQRQJaHpy"
addr1
:=
"16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
addr2
:=
"26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
addr3
:=
"36htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
addr4
:=
"46htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
accCoin
:=
account
.
NewCoinsAccount
()
account1
:=
&
types
.
Account
{
Balance
:
1000
*
1e8
,
Addr
:
addr1
,
}
account2
:=
&
types
.
Account
{
Balance
:
900
*
1e8
,
Addr
:
addr2
,
}
account3
:=
&
types
.
Account
{
Balance
:
800
*
1e8
,
Addr
:
addr3
,
}
account4
:=
&
types
.
Account
{
Balance
:
700
*
1e8
,
Addr
:
addr4
,
}
set1
:=
accCoin
.
GetKVSet
(
account1
)
set2
:=
accCoin
.
GetKVSet
(
account2
)
set3
:=
accCoin
.
GetKVSet
(
account3
)
set4
:=
accCoin
.
GetKVSet
(
account4
)
set5
:=
accCoin
.
GetExecKVSet
(
execaddr
,
account4
)
fmt
.
Println
(
"---test case1-1 ---"
)
var
kv
[]
*
types
.
KeyValue
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
set4
[
0
]
.
GetKey
(),
Value
:
set4
[
0
]
.
GetValue
()})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
set3
[
0
]
.
GetKey
(),
Value
:
set3
[
0
]
.
GetValue
()})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
set1
[
0
]
.
GetKey
(),
Value
:
set1
[
0
]
.
GetValue
()})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
set2
[
0
]
.
GetKey
(),
Value
:
set2
[
0
]
.
GetValue
()})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
set5
[
0
]
.
GetKey
(),
Value
:
set5
[
0
]
.
GetValue
()})
for
i
:=
0
;
i
<
len
(
kv
);
i
++
{
fmt
.
Println
(
"key:"
,
string
(
kv
[
i
]
.
Key
),
"value:"
,
string
(
kv
[
i
]
.
Value
))
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
var
kvset
[]
*
types
.
KeyValue
req
:=
&
types
.
ReqHash
{
Hash
:
hash
}
hash1
:=
make
([]
byte
,
len
(
hash
))
copy
(
hash1
,
hash
)
store
.
Commit
(
req
)
resp
:=
&
types
.
ReplyGetTotalCoins
{}
resp
.
Count
=
100000
store
.
IterateRangeByStateHash
(
hash
,
[]
byte
(
"mavl-coins-bty-"
),
[]
byte
(
"mavl-coins-bty-exec"
),
true
,
resp
.
IterateRangeByStateHash
)
fmt
.
Println
(
"resp.Num="
,
resp
.
Num
)
fmt
.
Println
(
"resp.Amount="
,
resp
.
Amount
)
assert
.
Equal
(
t
,
int64
(
4
),
resp
.
Num
)
assert
.
Equal
(
t
,
int64
(
340000000000
),
resp
.
Amount
)
fmt
.
Println
(
"---test case1-2 ---"
)
for
i
:=
1
;
i
<=
10
;
i
++
{
kvset
=
nil
s1
:=
fmt
.
Sprintf
(
"%03d"
,
11
-
i
)
addrx
:=
addr
+
s1
account
:=
&
types
.
Account
{
Balance
:
((
1000
+
int64
(
i
))
*
1e8
),
Addr
:
addrx
,
}
set
:=
accCoin
.
GetKVSet
(
account
)
fmt
.
Println
(
"key:"
,
string
(
set
[
0
]
.
GetKey
()),
"value:"
,
set
[
0
]
.
GetValue
())
kvset
=
append
(
kvset
,
&
types
.
KeyValue
{
Key
:
set
[
0
]
.
GetKey
(),
Value
:
set
[
0
]
.
GetValue
()})
datas1
:=
&
types
.
StoreSet
{
StateHash
:
hash1
,
KV
:
kvset
,
Height
:
datas
.
Height
+
int64
(
i
)}
hash1
,
err
=
store
.
MemSet
(
datas1
,
true
)
assert
.
Nil
(
t
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash1
}
store
.
Commit
(
req
)
}
resp
=
&
types
.
ReplyGetTotalCoins
{}
resp
.
Count
=
100000
store
.
IterateRangeByStateHash
(
hash1
,
[]
byte
(
"mavl-coins-bty-"
),
[]
byte
(
"mavl-coins-bty-exec"
),
true
,
resp
.
IterateRangeByStateHash
)
fmt
.
Println
(
"resp.Num="
,
resp
.
Num
)
fmt
.
Println
(
"resp.Amount="
,
resp
.
Amount
)
assert
.
Equal
(
t
,
int64
(
14
),
resp
.
Num
)
assert
.
Equal
(
t
,
int64
(
1345500000000
),
resp
.
Amount
)
fmt
.
Println
(
"---test case1-3 ---"
)
resp
=
&
types
.
ReplyGetTotalCoins
{}
resp
.
Count
=
100000
store
.
IterateRangeByStateHash
(
hash1
,
[]
byte
(
"mavl-coins-bty-06htvcBNSEA7fZhAdLJphDwQRQJaHpy003"
),
[]
byte
(
"mavl-coins-bty-exec"
),
true
,
resp
.
IterateRangeByStateHash
)
fmt
.
Println
(
"resp.Num="
,
resp
.
Num
)
fmt
.
Println
(
"resp.Amount="
,
resp
.
Amount
)
assert
.
Equal
(
t
,
int64
(
12
),
resp
.
Num
)
assert
.
Equal
(
t
,
int64
(
1143600000000
),
resp
.
Amount
)
fmt
.
Println
(
"---test case1-4 ---"
)
resp
=
&
types
.
ReplyGetTotalCoins
{}
resp
.
Count
=
2
store
.
IterateRangeByStateHash
(
hash1
,
[]
byte
(
"mavl-coins-bty-06htvcBNSEA7fZhAdLJphDwQRQJaHpy003"
),
[]
byte
(
"mavl-coins-bty-exec"
),
true
,
resp
.
IterateRangeByStateHash
)
fmt
.
Println
(
"resp.Num="
,
resp
.
Num
)
fmt
.
Println
(
"resp.Amount="
,
resp
.
Amount
)
assert
.
Equal
(
t
,
int64
(
2
),
resp
.
Num
)
assert
.
Equal
(
t
,
int64
(
201500000000
),
resp
.
Amount
)
fmt
.
Println
(
"---test case1-5 ---"
)
resp
=
&
types
.
ReplyGetTotalCoins
{}
resp
.
Count
=
2
store
.
IterateRangeByStateHash
(
hash1
,
[]
byte
(
"mavl-coins-bty-"
),
[]
byte
(
"mavl-coins-bty-exec"
),
true
,
resp
.
IterateRangeByStateHash
)
fmt
.
Println
(
"resp.Num="
,
resp
.
Num
)
fmt
.
Println
(
"resp.Amount="
,
resp
.
Amount
)
assert
.
Equal
(
t
,
int64
(
2
),
resp
.
Num
)
assert
.
Equal
(
t
,
int64
(
201900000000
),
resp
.
Amount
)
fmt
.
Println
(
"---test case1-6 ---"
)
resp
=
&
types
.
ReplyGetTotalCoins
{}
resp
.
Count
=
10000
store
.
IterateRangeByStateHash
(
hash
,
[]
byte
(
"mavl-coins-bty-"
),
[]
byte
(
"mavl-coins-bty-exec"
),
true
,
resp
.
IterateRangeByStateHash
)
fmt
.
Println
(
"resp.Num="
,
resp
.
Num
)
fmt
.
Println
(
"resp.Amount="
,
resp
.
Amount
)
assert
.
Equal
(
t
,
int64
(
0
),
resp
.
Num
)
assert
.
Equal
(
t
,
int64
(
0
),
resp
.
Amount
)
}
func
GetRandomString
(
length
int
)
string
{
return
common
.
GetRandPrintString
(
20
,
length
)
}
func
BenchmarkGet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
keys
[][]
byte
var
hash
=
drivers
.
EmptyRoot
[
:
]
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
:=
GetRandomString
(
MaxKeylenth
)
value
:=
fmt
.
Sprintf
(
"%s%d"
,
key
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
if
i
%
10000
==
0
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
,
Height
:
0
}
hash
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
kv
=
nil
}
}
if
kv
!=
nil
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
,
Height
:
0
}
hash
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
//kv = nil
}
assert
.
Nil
(
b
,
err
)
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
_
,
key
:=
range
keys
{
getData
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
[][]
byte
{
key
}}
store
.
Get
(
getData
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkGet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
func
BenchmarkStoreGetKvs4N
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
kvnum
:=
30
for
i
:=
0
;
i
<
kvnum
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
hash
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
getData
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
values
:=
store
.
Get
(
getData
)
assert
.
Len
(
b
,
values
,
kvnum
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkStoreGetKvs4N cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
func
BenchmarkStoreGetKvsForNN
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
var
hashes
[][]
byte
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
datas
.
Height
=
int64
(
i
)
value
=
fmt
.
Sprintf
(
"vv%d"
,
i
)
for
j
:=
0
;
j
<
30
;
j
++
{
datas
.
KV
[
j
]
.
Value
=
[]
byte
(
value
)
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
,
}
_
,
err
=
store
.
Commit
(
req
)
assert
.
NoError
(
b
,
err
,
"NoError"
)
datas
.
StateHash
=
hash
hashes
=
append
(
hashes
,
hash
)
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
getData
:=
&
types
.
StoreGet
{
StateHash
:
hashes
[
0
],
Keys
:
keys
}
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
getData
.
StateHash
=
hashes
[
i
]
store
.
Get
(
getData
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkStoreGetKvsForNN cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
func
BenchmarkStoreGetKvsFor10000
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
var
hashes
[][]
byte
blocks
:=
10000
times
:=
10000
start1
:=
time
.
Now
()
for
i
:=
0
;
i
<
blocks
;
i
++
{
datas
.
Height
=
int64
(
i
)
value
=
fmt
.
Sprintf
(
"vv%d"
,
i
)
for
j
:=
0
;
j
<
30
;
j
++
{
datas
.
KV
[
j
]
.
Value
=
[]
byte
(
value
)
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
,
}
_
,
err
=
store
.
Commit
(
req
)
assert
.
NoError
(
b
,
err
,
"NoError"
)
datas
.
StateHash
=
hash
hashes
=
append
(
hashes
,
hash
)
}
end1
:=
time
.
Now
()
start
:=
time
.
Now
()
b
.
ResetTimer
()
getData
:=
&
types
.
StoreGet
{
StateHash
:
hashes
[
0
],
Keys
:
keys
}
for
i
:=
0
;
i
<
times
;
i
++
{
getData
.
StateHash
=
hashes
[
i
]
store
.
Get
(
getData
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkStoreGetKvsFor10000 MemSet&Commit cost time is "
,
end1
.
Sub
(
start1
),
"blocks is"
,
blocks
)
fmt
.
Println
(
"kvmvcc BenchmarkStoreGetKvsFor10000 Get cost time is"
,
end
.
Sub
(
start
),
"num is "
,
times
,
",blocks is "
,
blocks
)
b
.
StopTimer
()
}
func
BenchmarkGetIter
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
storeCfg
,
sub
:=
newStoreCfgIter
(
dir
)
store
:=
New
(
storeCfg
,
sub
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
keys
[][]
byte
var
hash
=
drivers
.
EmptyRoot
[
:
]
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
:=
GetRandomString
(
MaxKeylenth
)
value
:=
fmt
.
Sprintf
(
"%s%d"
,
key
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
if
i
%
10000
==
0
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
,
Height
:
0
}
hash
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
kv
=
nil
}
}
if
kv
!=
nil
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
,
Height
:
0
}
hash
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
//kv = nil
}
assert
.
Nil
(
b
,
err
)
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
_
,
key
:=
range
keys
{
getData
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
[][]
byte
{
key
}}
store
.
Get
(
getData
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkGet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
func
BenchmarkSet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
b
.
Log
(
dir
)
var
kv
[]
*
types
.
KeyValue
var
keys
[][]
byte
var
hash
=
drivers
.
EmptyRoot
[
:
]
start
:=
time
.
Now
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
:=
GetRandomString
(
MaxKeylenth
)
value
:=
fmt
.
Sprintf
(
"%s%d"
,
key
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
if
i
%
10000
==
0
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
,
Height
:
0
}
hash
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
kv
=
nil
}
}
if
kv
!=
nil
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
,
Height
:
0
}
_
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
//kv = nil
}
end
:=
time
.
Now
()
fmt
.
Println
(
"mpt BenchmarkSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
//上一个用例,一次性插入多对kv;本用例每次插入30对kv,分多次插入,测试性能表现。
func
BenchmarkStoreSet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
hash
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
assert
.
NotNil
(
b
,
hash
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
func
BenchmarkSetIter
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
storeCfg
,
sub
:=
newStoreCfgIter
(
dir
)
store
:=
New
(
storeCfg
,
sub
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
b
.
Log
(
dir
)
var
kv
[]
*
types
.
KeyValue
var
keys
[][]
byte
var
hash
=
drivers
.
EmptyRoot
[
:
]
start
:=
time
.
Now
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
:=
GetRandomString
(
MaxKeylenth
)
value
:=
fmt
.
Sprintf
(
"%s%d"
,
key
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
if
i
%
10000
==
0
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
,
Height
:
0
}
hash
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
kv
=
nil
}
}
if
kv
!=
nil
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
,
Height
:
0
}
_
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
//kv = nil
}
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
func
isDirExists
(
path
string
)
bool
{
fi
,
err
:=
os
.
Stat
(
path
)
if
err
!=
nil
{
return
os
.
IsExist
(
err
)
}
return
fi
.
IsDir
()
}
//一次设定多对kv,测试一次的时间/多少对kv,来算平均一对kv的耗时。
func
BenchmarkMemSet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
assert
.
NotNil
(
b
,
hash
)
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkMemSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
//一次设定30对kv,设定N次,计算每次设定30对kv的耗时。
func
BenchmarkStoreMemSet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
assert
.
NotNil
(
b
,
hash
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
}
store
.
Rollback
(
req
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkStoreMemSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
func
BenchmarkCommit
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
,
}
_
,
err
=
store
.
Commit
(
req
)
assert
.
NoError
(
b
,
err
,
"NoError"
)
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkCommit cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
func
BenchmarkStoreCommit
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
datas
.
Height
=
int64
(
i
)
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
,
}
_
,
err
=
store
.
Commit
(
req
)
assert
.
NoError
(
b
,
err
,
"NoError"
)
datas
.
StateHash
=
hash
}
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkStoreCommit cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
//一次设定多对kv,测试一次的时间/多少对kv,来算平均一对kv的耗时。
func
BenchmarkIterMemSet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
storeCfg
,
sub
:=
newStoreCfgIter
(
dir
)
store
:=
New
(
storeCfg
,
sub
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
assert
.
NotNil
(
b
,
hash
)
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkMemSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
func
BenchmarkIterCommit
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
storeCfg
,
sub
:=
newStoreCfgIter
(
dir
)
store
:=
New
(
storeCfg
,
sub
)
.
(
*
KVMVCCStore
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
string
(
key
)),
Value
:
[]
byte
(
string
(
value
))})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
Height
:
0
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
,
}
_
,
err
=
store
.
Commit
(
req
)
assert
.
NoError
(
b
,
err
,
"NoError"
)
end
:=
time
.
Now
()
fmt
.
Println
(
"kvmvcc BenchmarkCommit cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
plugin/store/kvmvccMavl/mavl_test.go
deleted
100644 → 0
View file @
db64ffcb
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
kvmvccMavl
import
(
"io/ioutil"
"os"
"testing"
"fmt"
"time"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common"
drivers
"github.com/33cn/chain33/system/store"
mavldb
"github.com/33cn/chain33/system/store/mavl/db"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
)
const
MaxKeylenth
int
=
64
func
newStoreCfg
(
dir
string
)
*
types
.
Store
{
return
&
types
.
Store
{
Name
:
"mavl_test"
,
Driver
:
"leveldb"
,
DbPath
:
dir
,
DbCache
:
100
}
}
func
TestKvdbNewClose
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
t
,
store
)
store
.
Close
()
}
func
TestKvddbSetGet
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
t
,
store
)
keys0
:=
[][]
byte
{[]
byte
(
"mk1"
),
[]
byte
(
"mk2"
)}
get0
:=
&
types
.
StoreGet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
Keys
:
keys0
}
values0
:=
store
.
Get
(
get0
)
mlog
.
Info
(
"info"
,
"info"
,
values0
)
// Get exist key, result nil
assert
.
Len
(
t
,
values0
,
2
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
values0
[
0
])
assert
.
Equal
(
t
,
[]
byte
(
nil
),
values0
[
1
])
var
kv
[]
*
types
.
KeyValue
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"k1"
),
Value
:
[]
byte
(
"v1"
)})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"k2"
),
Value
:
[]
byte
(
"v2"
)})
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
hash
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
keys
:=
[][]
byte
{[]
byte
(
"k1"
),
[]
byte
(
"k2"
)}
get1
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values
:=
store
.
Get
(
get1
)
assert
.
Len
(
t
,
values
,
2
)
assert
.
Equal
(
t
,
[]
byte
(
"v1"
),
values
[
0
])
assert
.
Equal
(
t
,
[]
byte
(
"v2"
),
values
[
1
])
keys
=
[][]
byte
{[]
byte
(
"k1"
)}
get2
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values2
:=
store
.
Get
(
get2
)
assert
.
Len
(
t
,
values2
,
1
)
assert
.
Equal
(
t
,
[]
byte
(
"v1"
),
values2
[
0
])
get3
:=
&
types
.
StoreGet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
Keys
:
keys
}
values3
:=
store
.
Get
(
get3
)
assert
.
Len
(
t
,
values3
,
1
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
values3
[
0
])
}
func
TestKvdbMemSet
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
t
,
store
)
var
kv
[]
*
types
.
KeyValue
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk1"
),
Value
:
[]
byte
(
"v1"
)})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk2"
),
Value
:
[]
byte
(
"v2"
)})
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
keys
:=
[][]
byte
{[]
byte
(
"mk1"
),
[]
byte
(
"mk2"
)}
get1
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values
:=
store
.
Get
(
get1
)
assert
.
Len
(
t
,
values
,
2
)
actHash
,
_
:=
store
.
Commit
(
&
types
.
ReqHash
{
Hash
:
hash
})
assert
.
Equal
(
t
,
hash
,
actHash
)
notExistHash
,
_
:=
store
.
Commit
(
&
types
.
ReqHash
{
Hash
:
drivers
.
EmptyRoot
[
:
]})
assert
.
Nil
(
t
,
notExistHash
)
}
func
TestKvdbRollback
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
t
,
store
)
var
kv
[]
*
types
.
KeyValue
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk1"
),
Value
:
[]
byte
(
"v1"
)})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk2"
),
Value
:
[]
byte
(
"v2"
)})
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
keys
:=
[][]
byte
{[]
byte
(
"mk1"
),
[]
byte
(
"mk2"
)}
get1
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
}
values
:=
store
.
Get
(
get1
)
assert
.
Len
(
t
,
values
,
2
)
actHash
,
_
:=
store
.
Rollback
(
&
types
.
ReqHash
{
Hash
:
hash
})
assert
.
Equal
(
t
,
hash
,
actHash
)
notExistHash
,
_
:=
store
.
Rollback
(
&
types
.
ReqHash
{
Hash
:
drivers
.
EmptyRoot
[
:
]})
assert
.
Nil
(
t
,
notExistHash
)
}
var
checkKVResult
[]
*
types
.
KeyValue
func
checkKV
(
k
,
v
[]
byte
)
bool
{
checkKVResult
=
append
(
checkKVResult
,
&
types
.
KeyValue
{
Key
:
k
,
Value
:
v
})
mlog
.
Debug
(
"checkKV"
,
"key"
,
string
(
k
),
"value"
,
string
(
v
))
return
false
}
func
TestKvdbIterate
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
t
,
store
)
var
kv
[]
*
types
.
KeyValue
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk1"
),
Value
:
[]
byte
(
"v1"
)})
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
"mk2"
),
Value
:
[]
byte
(
"v2"
)})
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
hash
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
store
.
IterateRangeByStateHash
(
hash
,
[]
byte
(
"mk1"
),
[]
byte
(
"mk3"
),
true
,
checkKV
)
assert
.
Len
(
t
,
checkKVResult
,
2
)
assert
.
Equal
(
t
,
[]
byte
(
"v1"
),
checkKVResult
[
0
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
"v2"
),
checkKVResult
[
1
]
.
Value
)
}
type
StatTool
struct
{
Amount
int64
AmountActive
int64
AmountFrozen
int64
}
func
(
t
*
StatTool
)
AddItem
(
value
[][]
byte
)
{
for
i
:=
0
;
i
<
len
(
value
);
i
++
{
var
acc
types
.
Account
err
:=
types
.
Decode
(
value
[
i
],
&
acc
)
if
err
!=
nil
{
return
}
t
.
Amount
+=
acc
.
Balance
t
.
Amount
+=
acc
.
Frozen
t
.
AmountActive
+=
acc
.
Balance
t
.
AmountFrozen
+=
acc
.
Frozen
}
}
func
(
t
*
StatTool
)
Reset
()
{
t
.
Amount
=
0
t
.
AmountActive
=
0
t
.
AmountFrozen
=
0
}
func
genPrefixEdge
(
prefix
[]
byte
)
(
r
[]
byte
)
{
for
j
:=
0
;
j
<
len
(
prefix
);
j
++
{
r
=
append
(
r
,
prefix
[
j
])
}
i
:=
len
(
prefix
)
-
1
for
i
>=
0
{
if
r
[
i
]
<
0xff
{
r
[
i
]
++
break
}
else
{
i
--
}
}
return
r
}
func
TestIterateCallBack_Mode1
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
store_cfg
=
newStoreCfg
(
dir
)
store
:=
New
(
store_cfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
t
,
store
)
//mavldb.EnableMavlPrefix(true)
//defer mavldb.EnableMavlPrefix(false)
//var accountdb *account.DB
accountdb
:=
account
.
NewCoinsAccount
()
key
:=
"mavl-coins-bty-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP"
prefix
:=
"mavl-coins-bty-exec-"
execAddr1
:=
"16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
addr
:=
"1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP"
var
acc
=
&
types
.
Account
{
Currency
:
0
,
Balance
:
1
,
Frozen
:
1
,
Addr
:
addr
,
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
accountdb
.
GetExecKVSet
(
execAddr1
,
acc
),
Height
:
0
}
hash0
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
execAddr2
:=
"26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
datas
=
&
types
.
StoreSet
{
StateHash
:
hash0
,
KV
:
accountdb
.
GetExecKVSet
(
execAddr2
,
acc
),
Height
:
1
}
hash1
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
execAddr3
:=
"36htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
datas
=
&
types
.
StoreSet
{
StateHash
:
hash1
,
KV
:
accountdb
.
GetExecKVSet
(
execAddr3
,
acc
),
Height
:
2
}
hash2
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
fmt
.
Println
(
"func TestIterateCallBack------test case1-------"
)
req
:=
&
types
.
StoreList
{
StateHash
:
hash2
,
Start
:
[]
byte
(
prefix
),
Suffix
:
[]
byte
(
addr
),
End
:
genPrefixEdge
([]
byte
(
prefix
)),
Count
:
5
,
Mode
:
1
}
query
:=
drivers
.
NewStoreListQuery
(
store
,
req
)
resp2
:=
query
.
Run
()
tool
:=
&
StatTool
{}
tool
.
AddItem
(
resp2
.
Values
)
assert
.
Equal
(
t
,
int64
(
3
),
resp2
.
Num
)
assert
.
Equal
(
t
,
(
0
),
len
(
resp2
.
NextKey
))
assert
.
Equal
(
t
,
(
3
),
len
(
resp2
.
Keys
))
assert
.
Equal
(
t
,
(
3
),
len
(
resp2
.
Values
))
assert
.
Equal
(
t
,
int64
(
6
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
3
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
3
),
tool
.
AmountFrozen
)
tool
.
Reset
()
fmt
.
Println
(
"func TestIterateCallBack------test case2-------"
)
resp1
:=
&
types
.
StoreListReply
{}
resp1
.
Suffix
=
[]
byte
(
addr
)
resp1
.
Start
=
[]
byte
(
prefix
)
resp1
.
End
=
genPrefixEdge
([]
byte
(
prefix
))
resp1
.
Count
=
5
resp1
.
Mode
=
1
query
=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp1
}
store
.
IterateRangeByStateHash
(
hash1
,
resp1
.
Start
,
resp1
.
End
,
true
,
query
.
IterateCallBack
)
tool
.
AddItem
(
resp1
.
Values
)
assert
.
Equal
(
t
,
int64
(
2
),
resp1
.
Num
)
assert
.
Equal
(
t
,
(
0
),
len
(
resp1
.
NextKey
))
assert
.
Equal
(
t
,
(
2
),
len
(
resp1
.
Keys
))
assert
.
Equal
(
t
,
(
2
),
len
(
resp1
.
Values
))
assert
.
Equal
(
t
,
int64
(
4
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
AmountFrozen
)
tool
.
Reset
()
fmt
.
Println
(
"func TestIterateCallBack------test case3-------"
)
resp0
:=
&
types
.
StoreListReply
{}
resp0
.
Suffix
=
[]
byte
(
addr
)
resp0
.
Start
=
[]
byte
(
prefix
)
resp0
.
End
=
genPrefixEdge
([]
byte
(
prefix
))
resp0
.
Count
=
5
resp0
.
Mode
=
1
query
=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp0
}
store
.
IterateRangeByStateHash
(
hash0
,
resp0
.
Start
,
resp0
.
End
,
true
,
query
.
IterateCallBack
)
tool
.
AddItem
(
resp0
.
Values
)
assert
.
Equal
(
t
,
int64
(
1
),
resp0
.
Num
)
assert
.
Equal
(
t
,
0
,
len
(
resp0
.
NextKey
))
assert
.
Equal
(
t
,
1
,
len
(
resp0
.
Keys
))
assert
.
Equal
(
t
,
1
,
len
(
resp0
.
Values
))
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountFrozen
)
tool
.
Reset
()
fmt
.
Println
(
"func TestIterateCallBack------test case4-------"
)
resp
:=
&
types
.
StoreListReply
{}
resp
.
Suffix
=
[]
byte
(
addr
)
resp
.
Start
=
[]
byte
(
prefix
)
resp
.
End
=
genPrefixEdge
([]
byte
(
prefix
))
resp
.
Count
=
1
resp
.
Mode
=
1
query
=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp
}
store
.
IterateRangeByStateHash
(
hash2
,
resp
.
Start
,
resp
.
End
,
true
,
query
.
IterateCallBack
)
tool
.
AddItem
(
resp
.
Values
)
assert
.
Equal
(
t
,
int64
(
1
),
resp
.
Num
)
assert
.
Equal
(
t
,
len
([]
byte
(
key
)),
len
(
resp
.
NextKey
))
assert
.
Equal
(
t
,
(
1
),
len
(
resp
.
Keys
))
assert
.
Equal
(
t
,
(
1
),
len
(
resp
.
Values
))
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountFrozen
)
tool
.
Reset
()
fmt
.
Println
(
"func TestIterateCallBack------test case5-------"
)
resp
=
&
types
.
StoreListReply
{}
resp
.
Suffix
=
[]
byte
(
addr
)
resp
.
Start
=
[]
byte
(
prefix
)
resp
.
End
=
genPrefixEdge
([]
byte
(
prefix
))
resp
.
Count
=
2
resp
.
Mode
=
1
query
=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp
}
store
.
IterateRangeByStateHash
(
hash2
,
resp
.
Start
,
resp
.
End
,
true
,
query
.
IterateCallBack
)
tool
.
AddItem
(
resp
.
Values
)
assert
.
Equal
(
t
,
int64
(
2
),
resp
.
Num
)
assert
.
Equal
(
t
,
len
([]
byte
(
key
)),
len
(
resp
.
NextKey
))
assert
.
Equal
(
t
,
(
2
),
len
(
resp
.
Keys
))
assert
.
Equal
(
t
,
(
2
),
len
(
resp
.
Values
))
assert
.
Equal
(
t
,
int64
(
4
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
AmountFrozen
)
tool
.
Reset
()
}
func
TestIterateCallBack_Mode2
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
store_cfg
=
newStoreCfg
(
dir
)
store
:=
New
(
store_cfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
t
,
store
)
//mavldb.EnableMavlPrefix(true)
//defer mavldb.EnableMavlPrefix(false)
//var accountdb *account.DB
accountdb
:=
account
.
NewCoinsAccount
()
key
:=
"mavl-coins-bty-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP"
prefix
:=
"mavl-coins-bty-exec-"
execAddr1
:=
"16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
addr
:=
"1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP"
var
acc
=
&
types
.
Account
{
Currency
:
0
,
Balance
:
1
,
Frozen
:
1
,
Addr
:
addr
,
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
accountdb
.
GetExecKVSet
(
execAddr1
,
acc
),
Height
:
0
}
hash0
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
execAddr2
:=
"26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
datas
=
&
types
.
StoreSet
{
StateHash
:
hash0
,
KV
:
accountdb
.
GetExecKVSet
(
execAddr2
,
acc
),
Height
:
1
}
hash1
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
execAddr3
:=
"36htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
datas
=
&
types
.
StoreSet
{
StateHash
:
hash1
,
KV
:
accountdb
.
GetExecKVSet
(
execAddr3
,
acc
),
Height
:
2
}
hash2
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
fmt
.
Println
(
"func TestIterateCallBack------test case1-------"
)
resp2
:=
&
types
.
StoreListReply
{}
resp2
.
Suffix
=
[]
byte
(
addr
)
resp2
.
Start
=
[]
byte
(
prefix
)
resp2
.
End
=
genPrefixEdge
([]
byte
(
prefix
))
resp2
.
Count
=
5
resp2
.
Mode
=
2
query
:=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp2
}
store
.
IterateRangeByStateHash
(
hash2
,
resp2
.
Start
,
nil
,
true
,
query
.
IterateCallBack
)
tool
:=
&
StatTool
{}
tool
.
AddItem
(
resp2
.
Values
)
assert
.
Equal
(
t
,
int64
(
3
),
resp2
.
Num
)
assert
.
Equal
(
t
,
(
0
),
len
(
resp2
.
NextKey
))
assert
.
Equal
(
t
,
(
3
),
len
(
resp2
.
Keys
))
assert
.
Equal
(
t
,
(
3
),
len
(
resp2
.
Values
))
assert
.
Equal
(
t
,
int64
(
6
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
3
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
3
),
tool
.
AmountFrozen
)
tool
.
Reset
()
fmt
.
Println
(
"func TestIterateCallBack------test case2-------"
)
resp1
:=
&
types
.
StoreListReply
{}
resp1
.
Suffix
=
[]
byte
(
addr
)
resp1
.
Start
=
[]
byte
(
prefix
)
resp1
.
End
=
genPrefixEdge
([]
byte
(
prefix
))
resp1
.
Count
=
5
resp1
.
Mode
=
2
query
=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp1
}
store
.
IterateRangeByStateHash
(
hash1
,
resp1
.
Start
,
resp1
.
End
,
true
,
query
.
IterateCallBack
)
tool
.
AddItem
(
resp1
.
Values
)
assert
.
Equal
(
t
,
int64
(
2
),
resp1
.
Num
)
assert
.
Equal
(
t
,
(
0
),
len
(
resp1
.
NextKey
))
assert
.
Equal
(
t
,
(
2
),
len
(
resp1
.
Keys
))
assert
.
Equal
(
t
,
(
2
),
len
(
resp1
.
Values
))
assert
.
Equal
(
t
,
int64
(
4
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
AmountFrozen
)
tool
.
Reset
()
fmt
.
Println
(
"func TestIterateCallBack------test case3-------"
)
resp0
:=
&
types
.
StoreListReply
{}
resp0
.
Suffix
=
[]
byte
(
addr
)
resp0
.
Start
=
[]
byte
(
prefix
)
resp0
.
End
=
genPrefixEdge
([]
byte
(
prefix
))
resp0
.
Count
=
5
resp0
.
Mode
=
2
query
=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp0
}
store
.
IterateRangeByStateHash
(
hash0
,
resp0
.
Start
,
nil
,
true
,
query
.
IterateCallBack
)
tool
.
AddItem
(
resp0
.
Values
)
assert
.
Equal
(
t
,
int64
(
1
),
resp0
.
Num
)
assert
.
Equal
(
t
,
(
0
),
len
(
resp0
.
NextKey
))
assert
.
Equal
(
t
,
(
1
),
len
(
resp0
.
Keys
))
assert
.
Equal
(
t
,
(
1
),
len
(
resp0
.
Values
))
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountFrozen
)
tool
.
Reset
()
fmt
.
Println
(
"func TestIterateCallBack------test case4-------"
)
resp
:=
&
types
.
StoreListReply
{}
resp
.
Suffix
=
[]
byte
(
addr
)
resp
.
Start
=
[]
byte
(
prefix
)
resp
.
End
=
genPrefixEdge
([]
byte
(
prefix
))
resp
.
Count
=
1
resp
.
Mode
=
2
query
=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp
}
store
.
IterateRangeByStateHash
(
hash2
,
resp
.
Start
,
nil
,
true
,
query
.
IterateCallBack
)
tool
.
AddItem
(
resp
.
Values
)
assert
.
Equal
(
t
,
int64
(
1
),
resp
.
Num
)
assert
.
Equal
(
t
,
len
([]
byte
(
key
)),
len
(
resp
.
NextKey
))
assert
.
Equal
(
t
,
(
1
),
len
(
resp
.
Keys
))
assert
.
Equal
(
t
,
(
1
),
len
(
resp
.
Values
))
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountFrozen
)
tool
.
Reset
()
fmt
.
Println
(
"func TestIterateCallBack------test case5-------"
)
resp
=
&
types
.
StoreListReply
{}
resp
.
Suffix
=
[]
byte
(
addr
)
resp
.
Start
=
[]
byte
(
prefix
)
resp
.
End
=
genPrefixEdge
([]
byte
(
prefix
))
resp
.
Count
=
2
resp
.
Mode
=
2
query
=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp
}
store
.
IterateRangeByStateHash
(
hash2
,
resp
.
Start
,
nil
,
true
,
query
.
IterateCallBack
)
tool
.
AddItem
(
resp
.
Values
)
assert
.
Equal
(
t
,
int64
(
2
),
resp
.
Num
)
assert
.
Equal
(
t
,
len
([]
byte
(
key
)),
len
(
resp
.
NextKey
))
assert
.
Equal
(
t
,
(
2
),
len
(
resp
.
Keys
))
assert
.
Equal
(
t
,
(
2
),
len
(
resp
.
Values
))
assert
.
Equal
(
t
,
int64
(
4
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
AmountFrozen
)
tool
.
Reset
()
fmt
.
Println
(
"func TestIterateCallBack------test case6-------"
)
resp
=
&
types
.
StoreListReply
{}
resp
.
End
=
[]
byte
(
addr
)
resp
.
Start
=
[]
byte
(
"mavl-coins-bty-exec-26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:"
)
resp
.
End
=
genPrefixEdge
([]
byte
(
"mavl-coins-bty-exec-26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:"
))
resp
.
Count
=
1
resp
.
Mode
=
2
query
=
&
drivers
.
StorelistQuery
{
StoreListReply
:
resp
}
store
.
IterateRangeByStateHash
(
hash2
,
resp
.
Start
,
resp
.
End
,
true
,
query
.
IterateCallBack
)
tool
.
AddItem
(
resp
.
Values
)
assert
.
Equal
(
t
,
int64
(
1
),
resp
.
Num
)
assert
.
Equal
(
t
,
len
([]
byte
(
key
)),
len
(
resp
.
NextKey
))
assert
.
Equal
(
t
,
(
1
),
len
(
resp
.
Keys
))
assert
.
Equal
(
t
,
(
1
),
len
(
resp
.
Values
))
assert
.
Equal
(
t
,
int64
(
2
),
tool
.
Amount
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountActive
)
assert
.
Equal
(
t
,
int64
(
1
),
tool
.
AmountFrozen
)
tool
.
Reset
()
}
func
GetRandomString
(
length
int
)
string
{
return
common
.
GetRandPrintString
(
20
,
length
)
}
func
TestKvdbIterateTimes
(
t
*
testing
.
T
)
{
checkKVResult
=
checkKVResult
[
:
0
]
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
t
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
t
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
for
i
:=
0
;
i
<
1000
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
hash
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
t
,
err
)
start
:=
time
.
Now
()
store
.
IterateRangeByStateHash
(
hash
,
nil
,
nil
,
true
,
checkKV
)
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl cost time is"
,
end
.
Sub
(
start
))
assert
.
Len
(
t
,
checkKVResult
,
1000
)
}
func
BenchmarkGet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
mavldb
.
EnableMavlPrefix
(
true
)
defer
mavldb
.
EnableMavlPrefix
(
false
)
var
kv
[]
*
types
.
KeyValue
var
keys
[][]
byte
var
hash
=
drivers
.
EmptyRoot
[
:
]
fmt
.
Println
(
"N = "
,
b
.
N
)
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
:=
GetRandomString
(
MaxKeylenth
)
value
:=
fmt
.
Sprintf
(
"%s%d"
,
key
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
if
i
%
10000
==
0
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
}
hash
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
kv
=
nil
}
}
if
kv
!=
nil
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
}
hash
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
_
,
key
:=
range
keys
{
getData
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
[][]
byte
{
key
},
}
store
.
Get
(
getData
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkGet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
//这个用例测试Store.Get接口,一次调用会返回一组kvs(30对kv);前一个用例每次查询一个kv。
func
BenchmarkStoreGetKvs4N
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
kvnum
:=
30
for
i
:=
0
;
i
<
kvnum
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
key
))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
hash
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
getData
:=
&
types
.
StoreGet
{
StateHash
:
hash
,
Keys
:
keys
,
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
values
:=
store
.
Get
(
getData
)
assert
.
Len
(
b
,
values
,
kvnum
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkStoreGetKvs4N cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
//这个用例测试Store.Get接口,一次调用会返回一组kvs(30对kv),数据构造模拟真实情况,N条数据、N次查询。
func
BenchmarkStoreGetKvsForNN
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
var
hashes
[][]
byte
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
datas
.
Height
=
int64
(
i
)
value
=
fmt
.
Sprintf
(
"vv%d"
,
i
)
for
j
:=
0
;
j
<
10
;
j
++
{
datas
.
KV
[
j
]
.
Value
=
[]
byte
(
value
)
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
,
}
_
,
err
=
store
.
Commit
(
req
)
assert
.
NoError
(
b
,
err
,
"NoError"
)
datas
.
StateHash
=
hash
hashes
=
append
(
hashes
,
hash
)
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
getData
:=
&
types
.
StoreGet
{
StateHash
:
hashes
[
0
],
Keys
:
keys
,
}
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
getData
.
StateHash
=
hashes
[
i
]
store
.
Get
(
getData
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkStoreGetKvsForNN cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
//这个用例测试Store.Get接口,一次调用会返回一组kvs(30对kv),数据构造模拟真实情况,预置10000条数据,重复调用10000次。
func
BenchmarkStoreGetKvsFor10000
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
var
hashes
[][]
byte
blocks
:=
10000
times
:=
10000
start1
:=
time
.
Now
()
for
i
:=
0
;
i
<
blocks
;
i
++
{
datas
.
Height
=
int64
(
i
)
value
=
fmt
.
Sprintf
(
"vv%d"
,
i
)
for
j
:=
0
;
j
<
30
;
j
++
{
datas
.
KV
[
j
]
.
Value
=
[]
byte
(
value
)
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
,
}
_
,
err
=
store
.
Commit
(
req
)
assert
.
NoError
(
b
,
err
,
"NoError"
)
datas
.
StateHash
=
hash
hashes
=
append
(
hashes
,
hash
)
}
end1
:=
time
.
Now
()
start
:=
time
.
Now
()
b
.
ResetTimer
()
getData
:=
&
types
.
StoreGet
{
StateHash
:
hashes
[
0
],
Keys
:
keys
,
}
for
i
:=
0
;
i
<
times
;
i
++
{
getData
.
StateHash
=
hashes
[
i
]
store
.
Get
(
getData
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkStoreGetKvsFor10000 MemSet&Commit cost time is "
,
end1
.
Sub
(
start1
),
"blocks is"
,
blocks
)
fmt
.
Println
(
"mavl BenchmarkStoreGetKvsFor10000 Get cost time is"
,
end
.
Sub
(
start
),
"num is "
,
times
,
",blocks is "
,
blocks
)
b
.
StopTimer
()
}
func
BenchmarkSet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
mavldb
.
EnableMavlPrefix
(
true
)
defer
mavldb
.
EnableMavlPrefix
(
false
)
var
kv
[]
*
types
.
KeyValue
var
keys
[][]
byte
var
hash
=
drivers
.
EmptyRoot
[
:
]
start
:=
time
.
Now
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
:=
GetRandomString
(
MaxKeylenth
)
value
:=
fmt
.
Sprintf
(
"%s%d"
,
key
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
if
i
%
10000
==
0
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
}
hash
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
kv
=
nil
}
}
if
kv
!=
nil
{
datas
:=
&
types
.
StoreSet
{
StateHash
:
hash
,
KV
:
kv
}
_
,
err
=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
//这个用例测试Store.Set接口,一次调用保存一组kvs(30对)到数据库中。
func
BenchmarkStoreSetKvs
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
hash
,
err
:=
store
.
Set
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
assert
.
NotNil
(
b
,
hash
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
func
BenchmarkMemSet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
assert
.
NotNil
(
b
,
hash
)
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkMemSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
//这个用例测试Store.MemSet接口,一次调用保存一组kvs(30对)到数据库中。
func
BenchmarkStoreMemSet
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
assert
.
NotNil
(
b
,
hash
)
}
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkMemSet cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
}
func
BenchmarkCommit
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
,
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
_
,
err
=
store
.
Commit
(
req
)
assert
.
NoError
(
b
,
err
,
"NoError"
)
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkCommit cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
//模拟真实的数据提交操作,数据之间的关系也保持正确(hash计算),统计的时间包括MemSet和Commit,可以减去之前用例中测试出来的MemSet的时间来估算Commit耗时
func
BenchmarkStoreCommit
(
b
*
testing
.
B
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"example"
)
assert
.
Nil
(
b
,
err
)
defer
os
.
RemoveAll
(
dir
)
// clean up
os
.
RemoveAll
(
dir
)
//删除已存在目录
var
storeCfg
=
newStoreCfg
(
dir
)
store
:=
New
(
storeCfg
,
nil
)
.
(
*
Store
)
assert
.
NotNil
(
b
,
store
)
var
kv
[]
*
types
.
KeyValue
var
key
string
var
value
string
var
keys
[][]
byte
for
i
:=
0
;
i
<
30
;
i
++
{
key
=
GetRandomString
(
MaxKeylenth
)
value
=
fmt
.
Sprintf
(
"v%d"
,
i
)
keys
=
append
(
keys
,
[]
byte
(
string
(
key
)))
kv
=
append
(
kv
,
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)})
}
datas
:=
&
types
.
StoreSet
{
StateHash
:
drivers
.
EmptyRoot
[
:
],
KV
:
kv
,
}
start
:=
time
.
Now
()
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
datas
.
Height
=
int64
(
i
)
value
=
fmt
.
Sprintf
(
"vv%d"
,
i
)
for
j
:=
0
;
j
<
10
;
j
++
{
datas
.
KV
[
j
]
.
Value
=
[]
byte
(
value
)
}
hash
,
err
:=
store
.
MemSet
(
datas
,
true
)
assert
.
Nil
(
b
,
err
)
req
:=
&
types
.
ReqHash
{
Hash
:
hash
,
}
_
,
err
=
store
.
Commit
(
req
)
assert
.
NoError
(
b
,
err
,
"NoError"
)
datas
.
StateHash
=
hash
}
end
:=
time
.
Now
()
fmt
.
Println
(
"mavl BenchmarkCommit cost time is"
,
end
.
Sub
(
start
),
"num is"
,
b
.
N
)
b
.
StopTimer
()
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment