Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Begin tidwall/btree #253

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@

name: Build & Push TM-DB-Testing
on:
workflow_dispatch:
pull_request:
paths:
- "tools/*"
push:
branches:
- master
paths:
- "tools/*"

jobs:
build:
Expand All @@ -25,7 +22,7 @@ jobs:
- name: Prepare
id: prep
run: |
DOCKER_IMAGE=tendermintdev/docker-tm-db-testing
DOCKER_IMAGE=ghcr.io/notional-labs/tm-db
VERSION=noop
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
Expand All @@ -41,16 +38,19 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to DockerHub
-
name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Publish to Docker Hub
- name: Publish to Github Container registry
uses: docker/build-push-action@v3
with:
context: ./tools
registry: ghcr.io
file: ./tools/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
push: true
tags: ${{ steps.prep.outputs.tags }}
7 changes: 7 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This configuration file was automatically generated by Gitpod.
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
# and commit this file to your remote git repository to share the goodness with others.

image: ghcr.io/notional-labs/tm-db

# this means that there's a one-click known good environment available to developers.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Go 1.13+

- **[GoLevelDB](https://github.com/syndtr/goleveldb) [stable]**: A pure Go implementation of [LevelDB](https://github.com/google/leveldb) (see below). Currently the default on-disk database used in the Cosmos SDK.

- **MemDB [stable]:** An in-memory database using [Google's B-tree package](https://github.com/google/btree). Has very high performance both for reads, writes, and range scans, but is not durable and will lose all data on process exit. Does not support transactions. Suitable for e.g. caches, working sets, and tests. Used for [IAVL](https://github.com/tendermint/iavl) working sets when the pruning strategy allows it.
- **MemDB [stable]:** An in-memory database using [Google's B-tree package](https://github.com/tidwall/btree). Has very high performance both for reads, writes, and range scans, but is not durable and will lose all data on process exit. Does not support transactions. Suitable for e.g. caches, working sets, and tests. Used for [IAVL](https://github.com/tendermint/iavl) working sets when the pruning strategy allows it.

- **[LevelDB](https://github.com/google/leveldb) [experimental]:** A [Go wrapper](https://github.com/jmhodges/levigo) around [LevelDB](https://github.com/google/leveldb). Uses LSM-trees for on-disk storage, which have good performance for write-heavy workloads, particularly on spinning disks, but requires periodic compaction to maintain decent read performance and reclaim disk space. Does not support transactions.

Expand Down
1 change: 1 addition & 0 deletions boltdb.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build boltdb
// +build boltdb

package db
Expand Down
1 change: 1 addition & 0 deletions boltdb_batch.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build boltdb
// +build boltdb

package db
Expand Down
1 change: 1 addition & 0 deletions boltdb_iterator.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build boltdb
// +build boltdb

package db
Expand Down
1 change: 1 addition & 0 deletions boltdb_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build boltdb
// +build boltdb

package db
Expand Down
1 change: 1 addition & 0 deletions cleveldb.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build cleveldb
// +build cleveldb

package db
Expand Down
1 change: 1 addition & 0 deletions cleveldb_batch.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build cleveldb
// +build cleveldb

package db
Expand Down
1 change: 1 addition & 0 deletions cleveldb_iterator.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build cleveldb
// +build cleveldb

package db
Expand Down
1 change: 1 addition & 0 deletions cleveldb_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build cleveldb
// +build cleveldb

package db
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
module github.com/tendermint/tm-db

go 1.17
go 1.18

require (
github.com/cosmos/gorocksdb v1.2.0
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/btree v1.0.0
github.com/jmhodges/levigo v1.0.0
github.com/stretchr/testify v1.7.1
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca
github.com/tidwall/btree v1.3.1
go.etcd.io/bbolt v1.3.6
google.golang.org/grpc v1.46.0
)
Expand Down
7 changes: 2 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk=
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
Expand Down Expand Up @@ -75,8 +72,6 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw=
github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
Expand Down Expand Up @@ -142,6 +137,8 @@ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMT
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk=
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
github.com/tidwall/btree v1.3.1 h1:636+tdVDs8Hjcf35Di260W2xCW4KuoXOKyk9QWOvCpA=
github.com/tidwall/btree v1.3.1/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
55 changes: 20 additions & 35 deletions memdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@ import (
"fmt"
"sync"

"github.com/google/btree"
)

const (
// The approximate number of items and children per B-tree node. Tuned with benchmarks.
bTreeDegree = 32
"github.com/tidwall/btree"
)

func init() {
Expand All @@ -25,20 +20,19 @@ type item struct {
value []byte
}

// Less implements btree.Item.
func (i *item) Less(other btree.Item) bool {
// this considers nil == []byte{}, but that's ok since we handle nil endpoints
// in iterators specially anyway
return bytes.Compare(i.key, other.(*item).key) == -1
type itemRef *item

func less(a, b itemRef) bool {
return bytes.Compare((a.key), b.key) == -1
}

// newKey creates a new key item.
func newKey(key []byte) *item {
func newKey(key []byte) itemRef {
return &item{key: key}
}

// newPair creates a new pair item.
func newPair(key, value []byte) *item {
func newPair(key, value []byte) itemRef {
return &item{key: key, value: value}
}

Expand All @@ -50,16 +44,17 @@ func newPair(key, value []byte) *item {
// important with MemDB.
type MemDB struct {
mtx sync.RWMutex
btree *btree.BTree
btree *btree.Generic[itemRef]
}

var _ DB = (*MemDB)(nil)

// NewMemDB creates a new in-memory database.
func NewMemDB() *MemDB {
database := &MemDB{
btree: btree.New(bTreeDegree),
btree: btree.NewGeneric[itemRef](less),
}

return database
}

Expand All @@ -68,12 +63,10 @@ func (db *MemDB) Get(key []byte) ([]byte, error) {
if len(key) == 0 {
return nil, errKeyEmpty
}
db.mtx.RLock()
defer db.mtx.RUnlock()

i := db.btree.Get(newKey(key))
if i != nil {
return i.(*item).value, nil
i, found := db.btree.Get(newKey(key))
if found {
return i.value, nil
}
return nil, nil
}
Expand All @@ -83,10 +76,10 @@ func (db *MemDB) Has(key []byte) (bool, error) {
if len(key) == 0 {
return false, errKeyEmpty
}
db.mtx.RLock()
defer db.mtx.RUnlock()

return db.btree.Has(newKey(key)), nil
_, found := db.btree.Get(newKey(key))

return found, nil
}

// Set implements DB.
Expand All @@ -97,16 +90,14 @@ func (db *MemDB) Set(key []byte, value []byte) error {
if value == nil {
return errValueNil
}
db.mtx.Lock()
defer db.mtx.Unlock()

db.set(key, value)
return nil
}

// set sets a value without locking the mutex.
func (db *MemDB) set(key []byte, value []byte) {
db.btree.ReplaceOrInsert(newPair(key, value))
db.btree.Set(newPair(key, value))
}

// SetSync implements DB.
Expand Down Expand Up @@ -146,22 +137,16 @@ func (db *MemDB) Close() error {

// Print implements DB.
func (db *MemDB) Print() error {
db.mtx.RLock()
defer db.mtx.RUnlock()

db.btree.Ascend(func(i btree.Item) bool {
item := i.(*item)
fmt.Printf("[%X]:\t[%X]\n", item.key, item.value)
db.btree.Ascend(nil, func(i itemRef) bool {
pitem := i
fmt.Printf("[%X]:\t[%X]\n", pitem.key, pitem.value)
return true
})
return nil
}

// Stats implements DB.
func (db *MemDB) Stats() map[string]string {
db.mtx.RLock()
defer db.mtx.RUnlock()

stats := make(map[string]string)
stats["database.type"] = "memDB"
stats["database.size"] = fmt.Sprintf("%d", db.btree.Len())
Expand Down
2 changes: 1 addition & 1 deletion memdb_iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"bytes"
"context"

"github.com/google/btree"
"github.com/tidwall/btree"
)

const (
Expand Down
1 change: 1 addition & 0 deletions rocksdb.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build rocksdb
// +build rocksdb

package db
Expand Down
1 change: 1 addition & 0 deletions rocksdb_batch.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build rocksdb
// +build rocksdb

package db
Expand Down
1 change: 1 addition & 0 deletions rocksdb_iterator.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build rocksdb
// +build rocksdb

package db
Expand Down
1 change: 1 addition & 0 deletions rocksdb_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build rocksdb
// +build rocksdb

package db
Expand Down
2 changes: 1 addition & 1 deletion tools/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# updates here, merge the changes here first and let the image get updated (or
# push a new version manually) before PRs that depend on them.

FROM golang:1.17-bullseye AS build
FROM golang:1.18-bullseye AS build

ENV LD_LIBRARY_PATH=/usr/local/lib

Expand Down