diff --git a/bitcask.go b/bitcask.go index fab6bdf..5aa2df4 100644 --- a/bitcask.go +++ b/bitcask.go @@ -13,7 +13,9 @@ import ( ) var ( - ErrKeyNotFound = errors.New("error: key not found") + 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") ) @@ -67,6 +69,13 @@ 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 + } + if len(value) > b.opts.MaxValueSize { + return ErrValueTooLarge + } + index, err := b.put(key, value) if err != nil { return err diff --git a/bitcask_test.go b/bitcask_test.go index 0f4ecc1..350927d 100644 --- a/bitcask_test.go +++ b/bitcask_test.go @@ -128,6 +128,54 @@ func TestDeletedKeys(t *testing.T) { }) } +func TestMaxKeySize(t *testing.T) { + assert := assert.New(t) + + testdir, err := ioutil.TempDir("", "bitcask") + assert.NoError(err) + + var db *Bitcask + + size := 16 + + t.Run("Open", func(t *testing.T) { + db, err = Open(testdir, WithMaxKeySize(size)) + assert.NoError(err) + }) + + t.Run("Put", func(t *testing.T) { + key := strings.Repeat(" ", size+1) + value := []byte("foobar") + err = db.Put(key, value) + assert.Error(err) + assert.Equal("error: key too large", err.Error()) + }) +} + +func TestMaxValueSize(t *testing.T) { + assert := assert.New(t) + + testdir, err := ioutil.TempDir("", "bitcask") + assert.NoError(err) + + var db *Bitcask + + size := 16 + + t.Run("Open", func(t *testing.T) { + db, err = Open(testdir, WithMaxValueSize(size)) + assert.NoError(err) + }) + + t.Run("Put", func(t *testing.T) { + key := "foo" + value := []byte(strings.Repeat(" ", size+1)) + err = db.Put(key, value) + assert.Error(err) + assert.Equal("error: value too large", err.Error()) + }) +} + func TestMerge(t *testing.T) { assert := assert.New(t)