From b3d6f734b647a18cdc019de8754d5aa2357cd37a Mon Sep 17 00:00:00 2001 From: James Mills <1290234+prologic@users.noreply.github.com> Date: Fri, 30 Aug 2019 08:13:24 +1000 Subject: [PATCH] Use an Adaptive Radix Tree (#71) --- bitcask.go | 26 +++++++++++++------------- go.mod | 1 + go.sum | 2 ++ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/bitcask.go b/bitcask.go index 38e9138..c923f32 100644 --- a/bitcask.go +++ b/bitcask.go @@ -12,8 +12,8 @@ import ( "path/filepath" "sync" - "github.com/derekparker/trie" "github.com/gofrs/flock" + "github.com/plar/go-adaptive-radix-tree" "github.com/prologic/bitcask/internal" ) @@ -53,7 +53,7 @@ type Bitcask struct { curr *internal.Datafile keydir *internal.Keydir datafiles map[int]*internal.Datafile - trie *trie.Trie + trie art.Tree } // Stats is a struct returned by Stats() on an open Bitcask instance @@ -165,7 +165,7 @@ func (b *Bitcask) Put(key, value []byte) error { item := b.keydir.Add(key, b.curr.FileID(), offset, n) if b.config.greedyScan { - b.trie.Add(string(key), item) + b.trie.Insert(key, item) } return nil @@ -182,7 +182,7 @@ func (b *Bitcask) Delete(key []byte) error { b.keydir.Delete(key) if b.config.greedyScan { - b.trie.Remove(string(key)) + b.trie.Delete(key) } return nil @@ -193,12 +193,12 @@ func (b *Bitcask) Delete(key []byte) error { // no further keys are processed and the first error returned. func (b *Bitcask) Scan(prefix []byte, f func(key []byte) error) error { if b.config.greedyScan { - keys := b.trie.PrefixSearch(string(prefix)) - for _, key := range keys { - if err := f([]byte(key)); err != nil { - return err + b.trie.ForEachPrefix(prefix, func(node art.Node) bool { + if err := f(node.Key()); err != nil { + return false } - } + return true + }) return nil } @@ -316,9 +316,9 @@ func (b *Bitcask) reopen() error { keydir := internal.NewKeydir() - var t *trie.Trie + var t art.Tree if b.config.greedyScan { - t = trie.New() + t = art.New() } if internal.Exists(path.Join(b.path, "index")) { @@ -328,7 +328,7 @@ func (b *Bitcask) reopen() error { for key := range keydir.Keys() { item, _ := keydir.Get(key) if b.config.greedyScan { - t.Add(string(key), item) + t.Insert(key, item) } } } else { @@ -350,7 +350,7 @@ func (b *Bitcask) reopen() error { item := keydir.Add(e.Key, ids[i], e.Offset, n) if b.config.greedyScan { - t.Add(string(e.Key), item) + t.Insert(e.Key, item) } } } diff --git a/go.mod b/go.mod index 15577ef..6fa6e77 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/magiconair/properties v1.8.1 // indirect github.com/pelletier/go-toml v1.4.0 // indirect github.com/pkg/errors v0.8.1 + github.com/plar/go-adaptive-radix-tree v1.0.1 github.com/sirupsen/logrus v1.4.2 github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cobra v0.0.5 diff --git a/go.sum b/go.sum index e4305d1..869781d 100644 --- a/go.sum +++ b/go.sum @@ -80,6 +80,8 @@ github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUr github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/plar/go-adaptive-radix-tree v1.0.1 h1:J+2qrXaKWLACw59s8SlTVYYxWjlUr/BlCsfkAzn96/0= +github.com/plar/go-adaptive-radix-tree v1.0.1/go.mod h1:Ot8d28EII3i7Lv4PSvBlF8ejiD/CtRYDuPsySJbSaK8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=