mirror of
https://github.com/taigrr/bitcask
synced 2025-01-18 04:03:17 -08:00
Make optimised scan functionality optional (#68)
This commit is contained in:
parent
156d29e344
commit
e8bee948bc
38
bitcask.go
38
bitcask.go
@ -1,6 +1,7 @@
|
|||||||
package bitcask
|
package bitcask
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
@ -162,7 +163,10 @@ func (b *Bitcask) Put(key, value []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
item := b.keydir.Add(key, b.curr.FileID(), offset, n)
|
item := b.keydir.Add(key, b.curr.FileID(), offset, n)
|
||||||
|
|
||||||
|
if b.config.greedyScan {
|
||||||
b.trie.Add(string(key), item)
|
b.trie.Add(string(key), item)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -176,7 +180,10 @@ func (b *Bitcask) Delete(key []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
b.keydir.Delete(key)
|
b.keydir.Delete(key)
|
||||||
|
|
||||||
|
if b.config.greedyScan {
|
||||||
b.trie.Remove(string(key))
|
b.trie.Remove(string(key))
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -185,6 +192,7 @@ func (b *Bitcask) Delete(key []byte) error {
|
|||||||
// the function `f` with the keys found. If the function returns an error
|
// the function `f` with the keys found. If the function returns an error
|
||||||
// no further keys are processed and the first error returned.
|
// no further keys are processed and the first error returned.
|
||||||
func (b *Bitcask) Scan(prefix []byte, f func(key []byte) error) error {
|
func (b *Bitcask) Scan(prefix []byte, f func(key []byte) error) error {
|
||||||
|
if b.config.greedyScan {
|
||||||
keys := b.trie.PrefixSearch(string(prefix))
|
keys := b.trie.PrefixSearch(string(prefix))
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
if err := f([]byte(key)); err != nil {
|
if err := f([]byte(key)); err != nil {
|
||||||
@ -194,6 +202,18 @@ func (b *Bitcask) Scan(prefix []byte, f func(key []byte) error) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keys := b.Keys()
|
||||||
|
for key := range keys {
|
||||||
|
if bytes.Equal(prefix, key[:len(prefix)]) {
|
||||||
|
if err := f([]byte(key)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Len returns the total number of keys in the database
|
// Len returns the total number of keys in the database
|
||||||
func (b *Bitcask) Len() int {
|
func (b *Bitcask) Len() int {
|
||||||
return b.keydir.Len()
|
return b.keydir.Len()
|
||||||
@ -295,7 +315,11 @@ func (b *Bitcask) reopen() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keydir := internal.NewKeydir()
|
keydir := internal.NewKeydir()
|
||||||
trie := trie.New()
|
|
||||||
|
var t *trie.Trie
|
||||||
|
if b.config.greedyScan {
|
||||||
|
t = trie.New()
|
||||||
|
}
|
||||||
|
|
||||||
if internal.Exists(path.Join(b.path, "index")) {
|
if internal.Exists(path.Join(b.path, "index")) {
|
||||||
if err := keydir.Load(path.Join(b.path, "index")); err != nil {
|
if err := keydir.Load(path.Join(b.path, "index")); err != nil {
|
||||||
@ -303,7 +327,9 @@ func (b *Bitcask) reopen() error {
|
|||||||
}
|
}
|
||||||
for key := range keydir.Keys() {
|
for key := range keydir.Keys() {
|
||||||
item, _ := keydir.Get(key)
|
item, _ := keydir.Get(key)
|
||||||
trie.Add(string(key), item)
|
if b.config.greedyScan {
|
||||||
|
t.Add(string(key), item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for i, df := range datafiles {
|
for i, df := range datafiles {
|
||||||
@ -323,7 +349,9 @@ func (b *Bitcask) reopen() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
item := keydir.Add(e.Key, ids[i], e.Offset, n)
|
item := keydir.Add(e.Key, ids[i], e.Offset, n)
|
||||||
trie.Add(string(e.Key), item)
|
if b.config.greedyScan {
|
||||||
|
t.Add(string(e.Key), item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,7 +371,9 @@ func (b *Bitcask) reopen() error {
|
|||||||
|
|
||||||
b.keydir = keydir
|
b.keydir = keydir
|
||||||
|
|
||||||
b.trie = trie
|
if b.config.greedyScan {
|
||||||
|
b.trie = t
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
14
options.go
14
options.go
@ -25,6 +25,7 @@ type config struct {
|
|||||||
maxKeySize int
|
maxKeySize int
|
||||||
maxValueSize int
|
maxValueSize int
|
||||||
sync bool
|
sync bool
|
||||||
|
greedyScan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *config) MarshalJSON() ([]byte, error) {
|
func (c *config) MarshalJSON() ([]byte, error) {
|
||||||
@ -33,11 +34,13 @@ func (c *config) MarshalJSON() ([]byte, error) {
|
|||||||
MaxKeySize int `json:"max_key_size"`
|
MaxKeySize int `json:"max_key_size"`
|
||||||
MaxValueSize int `json:"max_value_size"`
|
MaxValueSize int `json:"max_value_size"`
|
||||||
Sync bool `json:"sync"`
|
Sync bool `json:"sync"`
|
||||||
|
GreedyScan bool `json:"greedy_scan"`
|
||||||
}{
|
}{
|
||||||
MaxDatafileSize: c.maxDatafileSize,
|
MaxDatafileSize: c.maxDatafileSize,
|
||||||
MaxKeySize: c.maxKeySize,
|
MaxKeySize: c.maxKeySize,
|
||||||
MaxValueSize: c.maxValueSize,
|
MaxValueSize: c.maxValueSize,
|
||||||
Sync: c.sync,
|
Sync: c.sync,
|
||||||
|
GreedyScan: c.greedyScan,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +50,7 @@ func getConfig(path string) (*config, error) {
|
|||||||
MaxKeySize int `json:"max_key_size"`
|
MaxKeySize int `json:"max_key_size"`
|
||||||
MaxValueSize int `json:"max_value_size"`
|
MaxValueSize int `json:"max_value_size"`
|
||||||
Sync bool `json:"sync"`
|
Sync bool `json:"sync"`
|
||||||
|
GreedyScan bool `json:"greedy_scan"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var cfg Config
|
var cfg Config
|
||||||
@ -65,6 +69,7 @@ func getConfig(path string) (*config, error) {
|
|||||||
maxKeySize: cfg.MaxKeySize,
|
maxKeySize: cfg.MaxKeySize,
|
||||||
maxValueSize: cfg.MaxValueSize,
|
maxValueSize: cfg.MaxValueSize,
|
||||||
sync: cfg.Sync,
|
sync: cfg.Sync,
|
||||||
|
greedyScan: cfg.GreedyScan,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,3 +113,12 @@ func WithSync(sync bool) Option {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithGreedyScan enables faster Scan performance.
|
||||||
|
// This is disabled by default because it causes high memory usage.
|
||||||
|
func WithGreedyScan(enabled bool) Option {
|
||||||
|
return func(cfg *config) error {
|
||||||
|
cfg.greedyScan = enabled
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user