Skip to content

Commit e2b93d9

Browse files
committed
perf: switch to go-art
1 parent acd97fb commit e2b93d9

File tree

5 files changed

+84
-68
lines changed

5 files changed

+84
-68
lines changed

db/engine/put_get_test.go

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,51 @@
11
package engine
22

33
import (
4-
"fmt"
4+
"os"
5+
"testing"
6+
57
"github.com/ByteStorage/FlyDB/config"
68
"github.com/ByteStorage/FlyDB/lib/randkv"
79
"github.com/stretchr/testify/assert"
8-
"os"
9-
"testing"
10-
"time"
1110
)
1211

13-
func TestPutAndGet(t *testing.T) {
12+
func BenchmarkPut(b *testing.B) {
1413
opts := config.DefaultOptions
1514
dir, _ := os.MkdirTemp("", "flydb-benchmark")
1615
opts.DirPath = dir
1716
opts.DataFileSize = 64 * 1024 * 1024
1817
db, err := NewDB(opts)
1918
defer db.Clean()
20-
assert.Nil(t, err)
21-
assert.NotNil(t, db)
19+
assert.Nil(b, err)
20+
assert.NotNil(b, db)
2221

23-
start := time.Now()
24-
for n := 0; n < 500000; n++ {
22+
n := 0
23+
for b.Loop() {
2524
err = db.Put(randkv.GetTestKey(n), randkv.RandomValue(24))
26-
assert.Nil(t, err)
25+
assert.Nil(b, err)
26+
n++
2727
}
28-
end := time.Now()
29-
fmt.Println("put time: ", end.Sub(start).String())
28+
}
29+
30+
func BenchmarkGet(b *testing.B) {
31+
opts := config.DefaultOptions
32+
dir, _ := os.MkdirTemp("", "flydb-benchmark")
33+
opts.DirPath = dir
34+
opts.DataFileSize = 64 * 1024 * 1024
35+
db, err := NewDB(opts)
36+
defer db.Clean()
37+
assert.Nil(b, err)
38+
assert.NotNil(b, db)
39+
40+
for n := 0; n < b.N; n++ {
41+
err = db.Put(randkv.GetTestKey(n), randkv.RandomValue(24))
42+
assert.Nil(b, err)
43+
}
44+
45+
b.ResetTimer()
3046

31-
start = time.Now()
32-
for n := 0; n < 500000; n++ {
47+
for n := 0; n < b.N; n++ {
3348
_, err = db.Get(randkv.GetTestKey(n))
34-
assert.Nil(t, err)
49+
assert.Nil(b, err)
3550
}
36-
end = time.Now()
37-
fmt.Println("get time: ", end.Sub(start).String())
3851
}

db/index/art.go

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,26 @@ package index
22

33
import (
44
"bytes"
5-
"github.com/ByteStorage/FlyDB/db/data"
6-
art "github.com/plar/go-adaptive-radix-tree"
75
"sort"
86
"sync"
7+
8+
"github.com/ByteStorage/FlyDB/db/data"
9+
art "github.com/Clement-Jean/go-art"
910
)
1011

1112
// Adaptive Radix Tree Index
1213
// The following link is the ART library written by go.
1314
// If you need to know more about it, please go to the corresponding warehouse.
14-
// https://github.com/plar/go-adaptive-radix-tree
15+
// https://github.com/Clement-Jean/go-art
1516
type AdaptiveRadixTree struct {
16-
tree art.Tree
17+
tree art.Tree[[]byte, *data.LogRecordPst]
1718
lock *sync.RWMutex
1819
}
1920

2021
// NewART Initializes the adaptive radix tree index
2122
func NewART() *AdaptiveRadixTree {
2223
return &AdaptiveRadixTree{
23-
tree: art.New(),
24+
tree: art.NewAlphaSortedTree[[]byte, *data.LogRecordPst](),
2425
lock: new(sync.RWMutex),
2526
}
2627
}
@@ -39,21 +40,19 @@ func (artree *AdaptiveRadixTree) Get(key []byte) *data.LogRecordPst {
3940
if !found {
4041
return nil
4142
}
42-
return value.(*data.LogRecordPst)
43+
return value
4344
}
4445

4546
func (artree *AdaptiveRadixTree) Delete(key []byte) bool {
4647
artree.lock.Lock()
4748
defer artree.lock.Unlock()
48-
_, deleted := artree.tree.Delete(key)
49-
return deleted
49+
return artree.tree.Delete(key)
5050
}
5151

5252
func (artree *AdaptiveRadixTree) Size() int {
5353
artree.lock.RLock()
5454
defer artree.lock.RUnlock()
55-
size := artree.tree.Size()
56-
return size
55+
return artree.tree.Size()
5756
}
5857

5958
func (artree *AdaptiveRadixTree) Iterator(reverse bool) Iterator {
@@ -69,7 +68,7 @@ type ARTreeIterator struct {
6968
values []*Item // Key + Location index information
7069
}
7170

72-
func NewARTreeIterator(tree art.Tree, reverse bool) *ARTreeIterator {
71+
func NewARTreeIterator(tree art.Tree[[]byte, *data.LogRecordPst], reverse bool) *ARTreeIterator {
7372
// Estimate the expected slice capacity based on tree size
7473
expectedSize := tree.Size()
7574

@@ -80,26 +79,32 @@ func NewARTreeIterator(tree art.Tree, reverse bool) *ARTreeIterator {
8079
values := make([]*Item, 0, expectedSize)
8180

8281
// Store all the data in an array
83-
saveToValues := func(node art.Node) bool {
84-
item := &Item{
85-
key: node.Key(),
86-
pst: node.Value().(*data.LogRecordPst),
82+
if reverse {
83+
// Reverse the values slice if reverse is true
84+
for key, value := range tree.Backward() {
85+
item := &Item{
86+
key: key,
87+
pst: value,
88+
}
89+
mutex.Lock()
90+
91+
// Append item to values slice
92+
values = append(values, item)
93+
94+
mutex.Unlock()
8795
}
88-
mutex.Lock()
89-
90-
// Append item to values slice
91-
values = append(values, item)
92-
93-
mutex.Unlock()
96+
} else {
97+
for key, value := range tree.All() {
98+
item := &Item{
99+
key: key,
100+
pst: value,
101+
}
102+
mutex.Lock()
94103

95-
return true
96-
}
97-
tree.ForEach(saveToValues)
104+
// Append item to values slice
105+
values = append(values, item)
98106

99-
// Reverse the values slice if reverse is true
100-
if reverse {
101-
for i, j := 0, len(values)-1; i < j; i, j = i+1, j-1 {
102-
values[i], values[j] = values[j], values[i]
107+
mutex.Unlock()
103108
}
104109
}
105110

db/index/art_with_bloom.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
package index
22

33
import (
4+
"sync"
5+
46
"github.com/ByteStorage/FlyDB/db/data"
57
"github.com/ByteStorage/FlyDB/lib/bloom"
6-
art "github.com/plar/go-adaptive-radix-tree"
7-
"sync"
8+
art "github.com/Clement-Jean/go-art"
89
)
910

1011
// AdaptiveRadixTreeWithBloom Adaptive Radix Tree Index
1112
// The following link is the ART library written by go.
1213
// If you need to know more about it, please go to the corresponding warehouse.
13-
// https://github.com/plar/go-adaptive-radix-tree
14+
// https://github.com/Clement-Jean/go-art
1415
type AdaptiveRadixTreeWithBloom struct {
15-
tree art.Tree
16+
tree art.Tree[[]byte, *data.LogRecordPst]
1617
lock *sync.RWMutex
1718
filter *bloom.Filter
1819
}
1920

2021
// NewARTWithBloom Initializes the adaptive radix tree index
2122
func NewARTWithBloom() *AdaptiveRadixTreeWithBloom {
2223
return &AdaptiveRadixTreeWithBloom{
23-
tree: art.New(),
24+
tree: art.NewAlphaSortedTree[[]byte, *data.LogRecordPst](),
2425
lock: new(sync.RWMutex),
2526
filter: bloom.NewBloomFilter(1000, 0.01),
2627
}
@@ -44,7 +45,7 @@ func (artree *AdaptiveRadixTreeWithBloom) Get(key []byte) *data.LogRecordPst {
4445
if !found {
4546
return nil
4647
}
47-
return value.(*data.LogRecordPst)
48+
return value
4849
}
4950

5051
func (artree *AdaptiveRadixTreeWithBloom) Delete(key []byte) bool {
@@ -53,15 +54,13 @@ func (artree *AdaptiveRadixTreeWithBloom) Delete(key []byte) bool {
5354
}
5455
artree.lock.Lock()
5556
defer artree.lock.Unlock()
56-
_, deleted := artree.tree.Delete(key)
57-
return deleted
57+
return artree.tree.Delete(key)
5858
}
5959

6060
func (artree *AdaptiveRadixTreeWithBloom) Size() int {
6161
artree.lock.RLock()
6262
defer artree.lock.RUnlock()
63-
size := artree.tree.Size()
64-
return size
63+
return artree.tree.Size()
6564
}
6665

6766
func (artree *AdaptiveRadixTreeWithBloom) Iterator(reverse bool) Iterator {

go.mod

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
module github.com/ByteStorage/FlyDB
22

3-
go 1.18
3+
go 1.24.0
44

55
require (
6+
github.com/Clement-Jean/go-art v0.0.0-20250326081316-f1b2fb5e334c
67
github.com/bits-and-blooms/bitset v1.8.0
78
github.com/boltdb/bolt v1.3.1
89
github.com/bwmarrin/snowflake v0.3.0
@@ -17,13 +18,14 @@ require (
1718
github.com/hashicorp/raft-boltdb v0.0.0-20230125174641-2a8082862702
1819
github.com/klauspost/reedsolomon v1.11.7
1920
github.com/pkg/errors v0.9.1
20-
github.com/plar/go-adaptive-radix-tree v1.0.5
2121
github.com/spaolacci/murmur3 v1.1.0
2222
github.com/stretchr/testify v1.8.2
2323
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c
2424
go.etcd.io/bbolt v1.3.7
2525
go.uber.org/zap v1.24.0
2626
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
27+
golang.org/x/net v0.8.0
28+
golang.org/x/sys v0.6.0
2729
google.golang.org/grpc v1.55.0
2830
google.golang.org/protobuf v1.31.0
2931
)
@@ -47,14 +49,11 @@ require (
4749
github.com/kr/pretty v0.3.0 // indirect
4850
github.com/mattn/go-colorable v0.1.12 // indirect
4951
github.com/mattn/go-isatty v0.0.16 // indirect
50-
github.com/panjf2000/ants v1.3.0 // indirect
5152
github.com/pmezard/go-difflib v1.0.0 // indirect
5253
github.com/rogpeppe/go-internal v1.9.0 // indirect
5354
go.uber.org/atomic v1.7.0 // indirect
5455
go.uber.org/multierr v1.6.0 // indirect
55-
golang.org/x/net v0.8.0 // indirect
56-
golang.org/x/sys v0.6.0 // indirect
57-
golang.org/x/text v0.8.0 // indirect
56+
golang.org/x/text v0.23.0 // indirect
5857
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
5958
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
6059
gopkg.in/yaml.v3 v3.0.1 // indirect

go.sum

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/Clement-Jean/go-art v0.0.0-20250326081316-f1b2fb5e334c h1:rk07r6OAsuDIri5WashmUSWcIqzr0Ljp0emVJrlyqKQ=
2+
github.com/Clement-Jean/go-art v0.0.0-20250326081316-f1b2fb5e334c/go.mod h1:2I5OXlf3ctXzpdEfEidXwYYgT28ByMMzprFAW/HseNQ=
13
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
24
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
35
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
@@ -11,6 +13,7 @@ github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4
1113
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
1214
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
1315
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
16+
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
1417
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
1518
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
1619
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -75,6 +78,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
7578
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
7679
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
7780
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
81+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
7882
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
7983
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
8084
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
@@ -140,16 +144,12 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
140144
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
141145
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
142146
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
143-
github.com/panjf2000/ants v1.3.0 h1:8pQ+8leaLc9lys2viEEr8md0U4RN6uOSUCE9bOYjQ9M=
144-
github.com/panjf2000/ants v1.3.0/go.mod h1:AaACblRPzq35m1g3enqYcxspbbiOJJYaxU2wMpm1cXY=
145147
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
146148
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
147149
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
148150
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
149151
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
150152
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
151-
github.com/plar/go-adaptive-radix-tree v1.0.5 h1:rHR89qy/6c24TBAHullFMrJsU9hGlKmPibdBGU6/gbM=
152-
github.com/plar/go-adaptive-radix-tree v1.0.5/go.mod h1:15VOUO7R9MhJL8HOJdpydR0rvanrtRE6fA6XSa/tqWE=
153153
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
154154
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
155155
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -185,7 +185,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
185185
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
186186
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
187187
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
188-
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
189188
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
190189
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
191190
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok=
@@ -196,6 +195,7 @@ go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
196195
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
197196
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
198197
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
198+
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
199199
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
200200
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
201201
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
@@ -233,8 +233,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
233233
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
234234
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
235235
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
236-
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
237-
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
236+
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
237+
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
238238
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
239239
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA=
240240
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=

0 commit comments

Comments
 (0)