From a887b44f5b09797bc0ba53cd693c7adfb760218e Mon Sep 17 00:00:00 2001 From: "KIm, JinSan" Date: Mon, 29 Mar 2021 14:57:32 +0900 Subject: [PATCH] chore: package `prefixdb` (#6) --- goleveldb/iterator.go | 10 +--- metadb/backend_test.go | 3 +- metadb/util_test.go | 11 +++-- prefixdb_batch.go => prefixdb/batch.go | 22 +++++---- prefixdb.go => prefixdb/db.go | 50 ++++++++++---------- prefixdb_test.go => prefixdb/db_test.go | 15 +++--- prefixdb_iterator.go => prefixdb/iterator.go | 16 ++++--- util.go | 12 ++--- util_test.go | 12 ++--- 9 files changed, 78 insertions(+), 73 deletions(-) rename prefixdb_batch.go => prefixdb/batch.go (67%) rename prefixdb.go => prefixdb/db.go (78%) rename prefixdb_test.go => prefixdb/db_test.go (91%) rename prefixdb_iterator.go => prefixdb/iterator.go (88%) diff --git a/goleveldb/iterator.go b/goleveldb/iterator.go index 9915c11..d62d61e 100644 --- a/goleveldb/iterator.go +++ b/goleveldb/iterator.go @@ -99,7 +99,7 @@ func (itr *goLevelDBIterator) Key() []byte { // Key returns a copy of the current key. // See https://github.com/syndtr/goleveldb/blob/52c212e6c196a1404ea59592d3f1c227c9f034b2/leveldb/iterator/iter.go#L88 itr.assertIsValid() - return cp(itr.source.Key()) + return tmdb.Cp(itr.source.Key()) } // Value implements Iterator. @@ -107,13 +107,7 @@ func (itr *goLevelDBIterator) Value() []byte { // Value returns a copy of the current value. // See https://github.com/syndtr/goleveldb/blob/52c212e6c196a1404ea59592d3f1c227c9f034b2/leveldb/iterator/iter.go#L88 itr.assertIsValid() - return cp(itr.source.Value()) -} - -func cp(bz []byte) (ret []byte) { - ret = make([]byte, len(bz)) - copy(ret, bz) - return ret + return tmdb.Cp(itr.source.Value()) } // Next implements Iterator. diff --git a/metadb/backend_test.go b/metadb/backend_test.go index 376fb91..37c6d7f 100644 --- a/metadb/backend_test.go +++ b/metadb/backend_test.go @@ -11,6 +11,7 @@ import ( "github.com/line/tm-db/v2/goleveldb" "github.com/line/tm-db/v2/internal/dbtest" "github.com/line/tm-db/v2/memdb" + "github.com/line/tm-db/v2/prefixdb" "github.com/line/tm-db/v2/rocksdb" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -27,7 +28,7 @@ func init() { mdb.Set([]byte("test"), []byte{0}) mdb.Set([]byte("u"), []byte{21}) mdb.Set([]byte("z"), []byte{26}) - return tmdb.NewPrefixDB(mdb, []byte("test/")), nil + return prefixdb.NewDB(mdb, []byte("test/")), nil }, false) } diff --git a/metadb/util_test.go b/metadb/util_test.go index 9db59f0..9a0f8d5 100644 --- a/metadb/util_test.go +++ b/metadb/util_test.go @@ -10,6 +10,7 @@ import ( tmdb "github.com/line/tm-db/v2" "github.com/line/tm-db/v2/internal/dbtest" + "github.com/line/tm-db/v2/prefixdb" ) // Empty iterator for empty db. @@ -18,7 +19,7 @@ func TestPrefixIteratorNoMatchNil(t *testing.T) { t.Run(fmt.Sprintf("Prefix w/ backend %s", backend), func(t *testing.T) { db, dir := newTempDB(t, backend) defer os.RemoveAll(dir) - itr, err := tmdb.IteratePrefix(db, []byte("2")) + itr, err := prefixdb.IteratePrefix(db, []byte("2")) require.NoError(t, err) dbtest.Invalid(t, itr) @@ -37,7 +38,7 @@ func TestPrefixIteratorNoMatch1(t *testing.T) { t.Run(fmt.Sprintf("Prefix w/ backend %s", backend), func(t *testing.T) { db, dir := newTempDB(t, backend) defer os.RemoveAll(dir) - itr, err := tmdb.IteratePrefix(db, []byte("2")) + itr, err := prefixdb.IteratePrefix(db, []byte("2")) require.NoError(t, err) err = db.SetSync([]byte("1"), []byte("value_1")) require.NoError(t, err) @@ -55,7 +56,7 @@ func TestPrefixIteratorNoMatch2(t *testing.T) { defer os.RemoveAll(dir) err := db.SetSync([]byte("3"), []byte("value_3")) require.NoError(t, err) - itr, err := tmdb.IteratePrefix(db, []byte("4")) + itr, err := prefixdb.IteratePrefix(db, []byte("4")) require.NoError(t, err) dbtest.Invalid(t, itr) @@ -71,7 +72,7 @@ func TestPrefixIteratorMatch1(t *testing.T) { defer os.RemoveAll(dir) err := db.SetSync([]byte("2"), []byte("value_2")) require.NoError(t, err) - itr, err := tmdb.IteratePrefix(db, []byte("2")) + itr, err := prefixdb.IteratePrefix(db, []byte("2")) require.NoError(t, err) dbtest.Valid(t, itr, true) @@ -106,7 +107,7 @@ func TestPrefixIteratorMatches1N(t *testing.T) { require.NoError(t, err) err = db.SetSync([]byte("abcdefg"), []byte("value_3")) require.NoError(t, err) - itr, err := tmdb.IteratePrefix(db, []byte("a/")) + itr, err := prefixdb.IteratePrefix(db, []byte("a/")) require.NoError(t, err) dbtest.Valid(t, itr, true) diff --git a/prefixdb_batch.go b/prefixdb/batch.go similarity index 67% rename from prefixdb_batch.go rename to prefixdb/batch.go index 9124c84..e7d8f5a 100644 --- a/prefixdb_batch.go +++ b/prefixdb/batch.go @@ -1,13 +1,17 @@ -package db +package prefixdb + +import ( + tmdb "github.com/line/tm-db/v2" +) type prefixDBBatch struct { prefix []byte - source Batch + source tmdb.Batch } -var _ Batch = (*prefixDBBatch)(nil) +var _ tmdb.Batch = (*prefixDBBatch)(nil) -func newPrefixBatch(prefix []byte, source Batch) prefixDBBatch { +func newPrefixBatch(prefix []byte, source tmdb.Batch) prefixDBBatch { return prefixDBBatch{ prefix: prefix, source: source, @@ -17,21 +21,21 @@ func newPrefixBatch(prefix []byte, source Batch) prefixDBBatch { // Set implements Batch. func (pb prefixDBBatch) Set(key, value []byte) error { if len(key) == 0 { - return ErrKeyEmpty + return tmdb.ErrKeyEmpty } if value == nil { - return ErrValueNil + return tmdb.ErrValueNil } - pkey := concat(pb.prefix, key) + pkey := tmdb.Concat(pb.prefix, key) return pb.source.Set(pkey, value) } // Delete implements Batch. func (pb prefixDBBatch) Delete(key []byte) error { if len(key) == 0 { - return ErrKeyEmpty + return tmdb.ErrKeyEmpty } - pkey := concat(pb.prefix, key) + pkey := tmdb.Concat(pb.prefix, key) return pb.source.Delete(pkey) } diff --git a/prefixdb.go b/prefixdb/db.go similarity index 78% rename from prefixdb.go rename to prefixdb/db.go index bd85fdd..34fbc5b 100644 --- a/prefixdb.go +++ b/prefixdb/db.go @@ -1,21 +1,23 @@ -package db +package prefixdb import ( "fmt" "sync" + + tmdb "github.com/line/tm-db/v2" ) // PrefixDB wraps a namespace of another database as a logical database. type PrefixDB struct { mtx sync.Mutex prefix []byte - db DB + db tmdb.DB } -var _ DB = (*PrefixDB)(nil) +var _ tmdb.DB = (*PrefixDB)(nil) // NewPrefixDB lets you namespace multiple DBs within a single DB. -func NewPrefixDB(db DB, prefix []byte) *PrefixDB { +func NewDB(db tmdb.DB, prefix []byte) *PrefixDB { return &PrefixDB{ prefix: prefix, db: db, @@ -25,7 +27,7 @@ func NewPrefixDB(db DB, prefix []byte) *PrefixDB { // Get implements DB. func (pdb *PrefixDB) Get(key []byte) ([]byte, error) { if len(key) == 0 { - return nil, ErrKeyEmpty + return nil, tmdb.ErrKeyEmpty } pdb.mtx.Lock() defer pdb.mtx.Unlock() @@ -41,7 +43,7 @@ func (pdb *PrefixDB) Get(key []byte) ([]byte, error) { // Has implements DB. func (pdb *PrefixDB) Has(key []byte) (bool, error) { if len(key) == 0 { - return false, ErrKeyEmpty + return false, tmdb.ErrKeyEmpty } pdb.mtx.Lock() defer pdb.mtx.Unlock() @@ -57,10 +59,10 @@ func (pdb *PrefixDB) Has(key []byte) (bool, error) { // Set implements DB. func (pdb *PrefixDB) Set(key []byte, value []byte) error { if len(key) == 0 { - return ErrKeyEmpty + return tmdb.ErrKeyEmpty } if value == nil { - return ErrValueNil + return tmdb.ErrValueNil } pdb.mtx.Lock() defer pdb.mtx.Unlock() @@ -75,10 +77,10 @@ func (pdb *PrefixDB) Set(key []byte, value []byte) error { // SetSync implements DB. func (pdb *PrefixDB) SetSync(key []byte, value []byte) error { if len(key) == 0 { - return ErrKeyEmpty + return tmdb.ErrKeyEmpty } if value == nil { - return ErrValueNil + return tmdb.ErrValueNil } pdb.mtx.Lock() defer pdb.mtx.Unlock() @@ -89,7 +91,7 @@ func (pdb *PrefixDB) SetSync(key []byte, value []byte) error { // Delete implements DB. func (pdb *PrefixDB) Delete(key []byte) error { if len(key) == 0 { - return ErrKeyEmpty + return tmdb.ErrKeyEmpty } pdb.mtx.Lock() defer pdb.mtx.Unlock() @@ -100,7 +102,7 @@ func (pdb *PrefixDB) Delete(key []byte) error { // DeleteSync implements DB. func (pdb *PrefixDB) DeleteSync(key []byte) error { if len(key) == 0 { - return ErrKeyEmpty + return tmdb.ErrKeyEmpty } pdb.mtx.Lock() defer pdb.mtx.Unlock() @@ -109,19 +111,19 @@ func (pdb *PrefixDB) DeleteSync(key []byte) error { } // Iterator implements DB. -func (pdb *PrefixDB) Iterator(start, end []byte) (Iterator, error) { +func (pdb *PrefixDB) Iterator(start, end []byte) (tmdb.Iterator, error) { if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) { - return nil, ErrKeyEmpty + return nil, tmdb.ErrKeyEmpty } pdb.mtx.Lock() defer pdb.mtx.Unlock() var pstart, pend []byte - pstart = concat(pdb.prefix, start) + pstart = tmdb.Concat(pdb.prefix, start) if end == nil { - pend = cpIncr(pdb.prefix) + pend = tmdb.CpIncr(pdb.prefix) } else { - pend = concat(pdb.prefix, end) + pend = tmdb.Concat(pdb.prefix, end) } itr, err := pdb.db.Iterator(pstart, pend) if err != nil { @@ -132,19 +134,19 @@ func (pdb *PrefixDB) Iterator(start, end []byte) (Iterator, error) { } // ReverseIterator implements DB. -func (pdb *PrefixDB) ReverseIterator(start, end []byte) (Iterator, error) { +func (pdb *PrefixDB) ReverseIterator(start, end []byte) (tmdb.Iterator, error) { if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) { - return nil, ErrKeyEmpty + return nil, tmdb.ErrKeyEmpty } pdb.mtx.Lock() defer pdb.mtx.Unlock() var pstart, pend []byte - pstart = concat(pdb.prefix, start) + pstart = tmdb.Concat(pdb.prefix, start) if end == nil { - pend = cpIncr(pdb.prefix) + pend = tmdb.CpIncr(pdb.prefix) } else { - pend = concat(pdb.prefix, end) + pend = tmdb.Concat(pdb.prefix, end) } ritr, err := pdb.db.ReverseIterator(pstart, pend) if err != nil { @@ -155,7 +157,7 @@ func (pdb *PrefixDB) ReverseIterator(start, end []byte) (Iterator, error) { } // NewBatch implements DB. -func (pdb *PrefixDB) NewBatch() Batch { +func (pdb *PrefixDB) NewBatch() tmdb.Batch { pdb.mtx.Lock() defer pdb.mtx.Unlock() @@ -200,5 +202,5 @@ func (pdb *PrefixDB) Stats() map[string]string { } func (pdb *PrefixDB) prefixed(key []byte) []byte { - return concat(pdb.prefix, key) + return tmdb.Concat(pdb.prefix, key) } diff --git a/prefixdb_test.go b/prefixdb/db_test.go similarity index 91% rename from prefixdb_test.go rename to prefixdb/db_test.go index dfc91fd..e7fa129 100644 --- a/prefixdb_test.go +++ b/prefixdb/db_test.go @@ -1,4 +1,4 @@ -package db_test +package prefixdb_test import ( "testing" @@ -6,6 +6,7 @@ import ( tmdb "github.com/line/tm-db/v2" "github.com/line/tm-db/v2/internal/dbtest" "github.com/line/tm-db/v2/memdb" + "github.com/line/tm-db/v2/prefixdb" "github.com/stretchr/testify/require" ) @@ -25,7 +26,7 @@ func mockDBWithStuff(t *testing.T) tmdb.DB { func TestPrefixDBSimple(t *testing.T) { db := mockDBWithStuff(t) - pdb := tmdb.NewPrefixDB(db, []byte("key")) + pdb := prefixdb.NewDB(db, []byte("key")) dbtest.Value(t, pdb, []byte("key"), nil) dbtest.Value(t, pdb, []byte("key1"), nil) @@ -42,7 +43,7 @@ func TestPrefixDBSimple(t *testing.T) { func TestPrefixDBIterator1(t *testing.T) { db := mockDBWithStuff(t) - pdb := tmdb.NewPrefixDB(db, []byte("key")) + pdb := prefixdb.NewDB(db, []byte("key")) itr, err := pdb.Iterator(nil, nil) require.NoError(t, err) @@ -59,7 +60,7 @@ func TestPrefixDBIterator1(t *testing.T) { func TestPrefixDBReverseIterator1(t *testing.T) { db := mockDBWithStuff(t) - pdb := tmdb.NewPrefixDB(db, []byte("key")) + pdb := prefixdb.NewDB(db, []byte("key")) itr, err := pdb.ReverseIterator(nil, nil) require.NoError(t, err) @@ -76,7 +77,7 @@ func TestPrefixDBReverseIterator1(t *testing.T) { func TestPrefixDBReverseIterator5(t *testing.T) { db := mockDBWithStuff(t) - pdb := tmdb.NewPrefixDB(db, []byte("key")) + pdb := prefixdb.NewDB(db, []byte("key")) itr, err := pdb.ReverseIterator([]byte("1"), nil) require.NoError(t, err) @@ -93,7 +94,7 @@ func TestPrefixDBReverseIterator5(t *testing.T) { func TestPrefixDBReverseIterator6(t *testing.T) { db := mockDBWithStuff(t) - pdb := tmdb.NewPrefixDB(db, []byte("key")) + pdb := prefixdb.NewDB(db, []byte("key")) itr, err := pdb.ReverseIterator([]byte("2"), nil) require.NoError(t, err) @@ -108,7 +109,7 @@ func TestPrefixDBReverseIterator6(t *testing.T) { func TestPrefixDBReverseIterator7(t *testing.T) { db := mockDBWithStuff(t) - pdb := tmdb.NewPrefixDB(db, []byte("key")) + pdb := prefixdb.NewDB(db, []byte("key")) itr, err := pdb.ReverseIterator(nil, []byte("2")) require.NoError(t, err) diff --git a/prefixdb_iterator.go b/prefixdb/iterator.go similarity index 88% rename from prefixdb_iterator.go rename to prefixdb/iterator.go index 79e1ef7..e273807 100644 --- a/prefixdb_iterator.go +++ b/prefixdb/iterator.go @@ -1,20 +1,22 @@ -package db +package prefixdb import ( "bytes" "fmt" + + tmdb "github.com/line/tm-db/v2" ) // IteratePrefix is a convenience function for iterating over a key domain // restricted by prefix. -func IteratePrefix(db DB, prefix []byte) (Iterator, error) { +func IteratePrefix(db tmdb.DB, prefix []byte) (tmdb.Iterator, error) { var start, end []byte if len(prefix) == 0 { start = nil end = nil } else { - start = cp(prefix) - end = cpIncr(prefix) + start = tmdb.Cp(prefix) + end = tmdb.CpIncr(prefix) } itr, err := db.Iterator(start, end) if err != nil { @@ -28,14 +30,14 @@ type prefixDBIterator struct { prefix []byte start []byte end []byte - source Iterator + source tmdb.Iterator valid bool err error } -var _ Iterator = (*prefixDBIterator)(nil) +var _ tmdb.Iterator = (*prefixDBIterator)(nil) -func newPrefixIterator(prefix, start, end []byte, source Iterator) (*prefixDBIterator, error) { +func newPrefixIterator(prefix, start, end []byte, source tmdb.Iterator) (*prefixDBIterator, error) { pitrInvalid := &prefixDBIterator{ prefix: prefix, start: start, diff --git a/util.go b/util.go index c3c024e..e853636 100644 --- a/util.go +++ b/util.go @@ -5,20 +5,20 @@ import ( "os" ) -func cp(bz []byte) (ret []byte) { +func Cp(bz []byte) (ret []byte) { ret = make([]byte, len(bz)) copy(ret, bz) return ret } -func concat(bz1 []byte, bz2 []byte) (ret []byte) { +func Concat(bz1 []byte, bz2 []byte) (ret []byte) { bz1len := len(bz1) if bz1len == 0 { - return cp(bz2) + return Cp(bz2) } bz2len := len(bz2) if bz2len == 0 { - return cp(bz1) + return Cp(bz1) } ret = make([]byte, bz1len+bz2len) @@ -31,11 +31,11 @@ func concat(bz1 []byte, bz2 []byte) (ret []byte) { // except incremented by one. // Returns nil on overflow (e.g. if bz bytes are all 0xFF) // CONTRACT: len(bz) > 0 -func cpIncr(bz []byte) (ret []byte) { +func CpIncr(bz []byte) (ret []byte) { if len(bz) == 0 { panic("cpIncr expects non-zero bz length") } - ret = cp(bz) + ret = Cp(bz) for i := len(bz) - 1; i >= 0; i-- { if ret[i] < byte(0xFF) { ret[i]++ diff --git a/util_test.go b/util_test.go index d71f2b3..ebf0440 100644 --- a/util_test.go +++ b/util_test.go @@ -10,7 +10,7 @@ func BenchmarkConcat(b *testing.B) { bz1 := []byte("prefix") bz2 := []byte("key") for i := 0; i < b.N; i++ { - _ = concat(bz1, bz2) + _ = Concat(bz1, bz2) } } @@ -18,7 +18,7 @@ func BenchmarkPrefixed(b *testing.B) { bz1 := []byte("prefix") bz2 := []byte("key") for i := 0; i < b.N; i++ { - _ = append(cp(bz1), bz2...) + _ = append(Cp(bz1), bz2...) } } @@ -32,8 +32,8 @@ func BenchmarkBytesJoin(b *testing.B) { func TestConcat(t *testing.T) { prefix := []byte("prefix") key := []byte("key") - require.Equal(t, bytes.Join([][]byte{prefix, key}, nil), concat(prefix, key)) - require.Equal(t, prefix, concat(prefix, nil)) - require.Equal(t, key, concat(nil, key)) - require.Equal(t, []byte{}, concat(nil, nil)) + require.Equal(t, bytes.Join([][]byte{prefix, key}, nil), Concat(prefix, key)) + require.Equal(t, prefix, Concat(prefix, nil)) + require.Equal(t, key, Concat(nil, key)) + require.Equal(t, []byte{}, Concat(nil, nil)) }