1
0
mirror of https://github.com/taigrr/bitcask synced 2025-01-18 04:03:17 -08:00

Fixed read performance by ~6x in general by caching all inactive datafiles. Fixes #1

This commit is contained in:
James Mills 2019-03-13 19:24:35 +10:00
parent 108cb54cb2
commit f88919ecd0
No known key found for this signature in database
GPG Key ID: AC4C014F1440EBD6

View File

@ -25,11 +25,15 @@ type Bitcask struct {
path string path string
curr *Datafile curr *Datafile
keydir *Keydir keydir *Keydir
datafiles []*Datafile
maxDatafileSize int64 maxDatafileSize int64
} }
func (b *Bitcask) Close() error { func (b *Bitcask) Close() error {
for _, df := range b.datafiles {
df.Close()
}
return b.curr.Close() return b.curr.Close()
} }
@ -38,26 +42,17 @@ func (b *Bitcask) Sync() error {
} }
func (b *Bitcask) Get(key string) ([]byte, error) { func (b *Bitcask) Get(key string) ([]byte, error) {
var df *Datafile
item, ok := b.keydir.Get(key) item, ok := b.keydir.Get(key)
if !ok { if !ok {
return nil, ErrKeyNotFound return nil, ErrKeyNotFound
} }
var (
df *Datafile
err error
)
// Optimization
if item.FileID == b.curr.id { if item.FileID == b.curr.id {
df = b.curr df = b.curr
} else { } else {
// TODO: Pre-open non-active Datafiles and cache the file pointers? df = b.datafiles[item.FileID]
df, err = NewDatafile(b.path, item.FileID, true)
if err != nil {
return nil, err
}
defer df.Close()
} }
e, err := df.ReadAt(item.Index) e, err := df.ReadAt(item.Index)
@ -111,6 +106,9 @@ func (b *Bitcask) put(key string, value []byte) (int64, error) {
return -1, err return -1, err
} }
df, err := NewDatafile(b.path, b.curr.id, true)
b.datafiles = append(b.datafiles, df)
id := b.curr.id + 1 id := b.curr.id + 1
curr, err := NewDatafile(b.path, id, false) curr, err := NewDatafile(b.path, id, false)
if err != nil { if err != nil {
@ -277,8 +275,6 @@ func Open(path string, options ...func(*Bitcask) error) (*Bitcask, error) {
return nil, err return nil, err
} }
keydir := NewKeydir()
fns, err := getDatafiles(path) fns, err := getDatafiles(path)
if err != nil { if err != nil {
return nil, err return nil, err
@ -289,7 +285,16 @@ func Open(path string, options ...func(*Bitcask) error) (*Bitcask, error) {
return nil, err return nil, err
} }
keydir := NewKeydir()
var datafiles []*Datafile
for i, fn := range fns { for i, fn := range fns {
df, err := NewDatafile(path, ids[i], true)
if err != nil {
return nil, err
}
datafiles = append(datafiles, df)
if filepath.Ext(fn) == ".hint" { if filepath.Ext(fn) == ".hint" {
f, err := os.Open(filepath.Join(path, fn)) f, err := os.Open(filepath.Join(path, fn))
if err != nil { if err != nil {
@ -307,11 +312,6 @@ func Open(path string, options ...func(*Bitcask) error) (*Bitcask, error) {
keydir.Add(key, item.FileID, item.Index, item.Timestamp) keydir.Add(key, item.FileID, item.Index, item.Timestamp)
} }
} else { } else {
df, err := NewDatafile(path, ids[i], true)
if err != nil {
return nil, err
}
for { for {
e, err := df.Read() e, err := df.Read()
if err != nil { if err != nil {
@ -336,6 +336,7 @@ func Open(path string, options ...func(*Bitcask) error) (*Bitcask, error) {
if len(ids) > 0 { if len(ids) > 0 {
id = ids[(len(ids) - 1)] id = ids[(len(ids) - 1)]
} }
curr, err := NewDatafile(path, id, false) curr, err := NewDatafile(path, id, false)
if err != nil { if err != nil {
return nil, err return nil, err
@ -345,6 +346,7 @@ func Open(path string, options ...func(*Bitcask) error) (*Bitcask, error) {
path: path, path: path,
curr: curr, curr: curr,
keydir: keydir, keydir: keydir,
datafiles: datafiles,
maxDatafileSize: DefaultMaxDatafileSize, maxDatafileSize: DefaultMaxDatafileSize,
} }