mirror of
https://github.com/gogrlx/bitcask.git
synced 2026-04-04 12:02:46 -07:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
120e854444 | ||
|
|
d2f44d1513 |
19
bitcask.go
19
bitcask.go
@@ -1,7 +1,7 @@
|
||||
package bitcask
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -9,15 +9,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/derekparker/trie"
|
||||
"github.com/gofrs/flock"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrKeyNotFound = errors.New("error: key not found")
|
||||
ErrKeyTooLarge = errors.New("error: key too large")
|
||||
ErrValueTooLarge = errors.New("error: value too large")
|
||||
ErrDatabaseLocked = errors.New("error: database locked")
|
||||
"github.com/prologic/trie"
|
||||
)
|
||||
|
||||
type Bitcask struct {
|
||||
@@ -54,7 +47,7 @@ func (b *Bitcask) Get(key string) ([]byte, error) {
|
||||
|
||||
item, ok := b.keydir.Get(key)
|
||||
if !ok {
|
||||
return nil, ErrKeyNotFound
|
||||
return nil, fmt.Errorf("error: key not found %s", key)
|
||||
}
|
||||
|
||||
if item.FileID == b.curr.id {
|
||||
@@ -73,10 +66,10 @@ func (b *Bitcask) Get(key string) ([]byte, error) {
|
||||
|
||||
func (b *Bitcask) Put(key string, value []byte) error {
|
||||
if len(key) > b.opts.MaxKeySize {
|
||||
return ErrKeyTooLarge
|
||||
return fmt.Errorf("error: key too large %d > %d", len(key), b.opts.MaxKeySize)
|
||||
}
|
||||
if len(value) > b.opts.MaxValueSize {
|
||||
return ErrValueTooLarge
|
||||
return fmt.Errorf("error: value too large %d > %d", len(value), b.opts.MaxValueSize)
|
||||
}
|
||||
|
||||
index, err := b.put(key, value)
|
||||
@@ -365,7 +358,7 @@ func Open(path string, options ...func(*Bitcask) error) (*Bitcask, error) {
|
||||
}
|
||||
|
||||
if !locked {
|
||||
return nil, ErrDatabaseLocked
|
||||
return nil, fmt.Errorf("error: database locked %s", path)
|
||||
}
|
||||
|
||||
return bitcask, nil
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestAll(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
_, err = db.Get("foo")
|
||||
assert.Error(err)
|
||||
assert.Equal(err.Error(), "error: key not found")
|
||||
assert.Equal("error: key not found foo", err.Error())
|
||||
})
|
||||
|
||||
t.Run("Sync", func(t *testing.T) {
|
||||
@@ -92,7 +92,7 @@ func TestDeletedKeys(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
_, err = db.Get("foo")
|
||||
assert.Error(err)
|
||||
assert.Equal("error: key not found", err.Error())
|
||||
assert.Equal("error: key not found foo", err.Error())
|
||||
})
|
||||
|
||||
t.Run("Sync", func(t *testing.T) {
|
||||
@@ -120,7 +120,7 @@ func TestDeletedKeys(t *testing.T) {
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
_, err = db.Get("foo")
|
||||
assert.Error(err)
|
||||
assert.Equal("error: key not found", err.Error())
|
||||
assert.Equal("error: key not found foo", err.Error())
|
||||
})
|
||||
|
||||
t.Run("Close", func(t *testing.T) {
|
||||
@@ -138,19 +138,17 @@ func TestMaxKeySize(t *testing.T) {
|
||||
|
||||
var db *Bitcask
|
||||
|
||||
size := 16
|
||||
|
||||
t.Run("Open", func(t *testing.T) {
|
||||
db, err = Open(testdir, WithMaxKeySize(size))
|
||||
db, err = Open(testdir, WithMaxKeySize(16))
|
||||
assert.NoError(err)
|
||||
})
|
||||
|
||||
t.Run("Put", func(t *testing.T) {
|
||||
key := strings.Repeat(" ", size+1)
|
||||
key := strings.Repeat(" ", 17)
|
||||
value := []byte("foobar")
|
||||
err = db.Put(key, value)
|
||||
assert.Error(err)
|
||||
assert.Equal("error: key too large", err.Error())
|
||||
assert.Equal("error: key too large 17 > 16", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -162,19 +160,17 @@ func TestMaxValueSize(t *testing.T) {
|
||||
|
||||
var db *Bitcask
|
||||
|
||||
size := 16
|
||||
|
||||
t.Run("Open", func(t *testing.T) {
|
||||
db, err = Open(testdir, WithMaxValueSize(size))
|
||||
db, err = Open(testdir, WithMaxValueSize(16))
|
||||
assert.NoError(err)
|
||||
})
|
||||
|
||||
t.Run("Put", func(t *testing.T) {
|
||||
key := "foo"
|
||||
value := []byte(strings.Repeat(" ", size+1))
|
||||
value := []byte(strings.Repeat(" ", 17))
|
||||
err = db.Put(key, value)
|
||||
assert.Error(err)
|
||||
assert.Equal("error: value too large", err.Error())
|
||||
assert.Equal("error: value too large 17 > 16", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -393,7 +389,7 @@ func TestLocking(t *testing.T) {
|
||||
|
||||
_, err = Open(testdir)
|
||||
assert.Error(err)
|
||||
assert.Equal("error: database locked", err.Error())
|
||||
assert.Equal(fmt.Sprintf("error: database locked %s", testdir), err.Error())
|
||||
}
|
||||
|
||||
type benchmarkTestCase struct {
|
||||
|
||||
@@ -96,6 +96,8 @@ func (df *Datafile) Sync() error {
|
||||
}
|
||||
|
||||
func (df *Datafile) Size() (int64, error) {
|
||||
df.RLock()
|
||||
defer df.RUnlock()
|
||||
return df.offset, nil
|
||||
}
|
||||
|
||||
@@ -123,13 +125,13 @@ func (df *Datafile) Write(e pb.Entry) (int64, error) {
|
||||
return -1, ErrReadonly
|
||||
}
|
||||
|
||||
df.Lock()
|
||||
defer df.Unlock()
|
||||
|
||||
e.Index = df.offset
|
||||
e.Timestamp = time.Now().Unix()
|
||||
|
||||
df.Lock()
|
||||
n, err := df.enc.Encode(&e)
|
||||
df.Unlock()
|
||||
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
1
go.mod
1
go.mod
@@ -10,6 +10,7 @@ require (
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/prologic/msgbus v0.1.1
|
||||
github.com/prologic/trie v0.0.0-20190316011403-395e39dac705
|
||||
github.com/prometheus/client_golang v0.9.2 // indirect
|
||||
github.com/sirupsen/logrus v1.3.0
|
||||
github.com/spf13/cobra v0.0.3
|
||||
|
||||
2
go.sum
2
go.sum
@@ -42,6 +42,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
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/prologic/msgbus v0.1.1/go.mod h1:B3Qu4/U2FP08x93jUzp9E8bl155+cIgDH2DUGRK6OZk=
|
||||
github.com/prologic/trie v0.0.0-20190316011403-395e39dac705 h1:2J+cSlAeECj0lfMKSmM7n5OlIio+yLovaKLZJzwLc6U=
|
||||
github.com/prologic/trie v0.0.0-20190316011403-395e39dac705/go.mod h1:LFuDmpHJGmciXd8Rl5YMhVlLMps9gz2GtYLzwxrFhzs=
|
||||
github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
||||
|
||||
Reference in New Issue
Block a user