add some kv function

setrange, getrange, strlen, append
This commit is contained in:
siddontang 2015-02-05 09:30:04 +08:00
parent b5c78640aa
commit 926d082787
2 changed files with 181 additions and 0 deletions

View File

@ -394,3 +394,128 @@ func (db *DB) Persist(key []byte) (int64, error) {
err = t.Commit() err = t.Commit()
return n, err return n, err
} }
func (db *DB) SetRange(key []byte, offset int, value []byte) (int64, error) {
if len(value) == 0 {
return 0, nil
}
if err := checkKeySize(key); err != nil {
return 0, err
} else if len(value)+offset > MaxValueSize {
return 0, errValueSize
}
key = db.encodeKVKey(key)
t := db.kvBatch
t.Lock()
defer t.Unlock()
oldValue, err := db.bucket.Get(key)
if err != nil {
return 0, err
}
extra := offset + len(value) - len(oldValue)
if extra > 0 {
oldValue = append(oldValue, make([]byte, extra)...)
}
copy(oldValue[offset:], value)
t.Put(key, oldValue)
if err := t.Commit(); err != nil {
return 0, err
}
return int64(len(oldValue)), nil
}
func (db *DB) GetRange(key []byte, start int, end int) ([]byte, error) {
if err := checkKeySize(key); err != nil {
return nil, err
}
key = db.encodeKVKey(key)
value, err := db.bucket.Get(key)
if err != nil {
return nil, err
}
valLen := len(value)
if start < 0 {
start = valLen + start
}
if end < 0 {
end = valLen + end
}
if start < 0 {
start = 0
}
if end < 0 {
end = 0
}
if end >= valLen {
end = valLen - 1
}
if start > end {
return nil, nil
}
return value[start : end+1], nil
}
func (db *DB) StrLen(key []byte) (int64, error) {
s, err := db.GetSlice(key)
if err != nil {
return 0, err
}
n := s.Size()
s.Free()
return int64(n), nil
}
func (db *DB) Append(key []byte, value []byte) (int64, error) {
if len(value) == 0 {
return 0, nil
}
if err := checkKeySize(key); err != nil {
return 0, err
}
key = db.encodeKVKey(key)
t := db.kvBatch
t.Lock()
defer t.Unlock()
oldValue, err := db.bucket.Get(key)
if err != nil {
return 0, err
}
if len(oldValue)+len(value) > MaxValueSize {
return 0, errValueSize
}
oldValue = append(oldValue, value...)
t.Put(key, oldValue)
if err := t.Commit(); err != nil {
return 0, nil
}
return int64(len(oldValue)), nil
}

View File

@ -42,6 +42,62 @@ func TestDBKV(t *testing.T) {
t.Fatal(string(v2)) t.Fatal(string(v2))
} }
key3 := []byte("testdb_kv_range")
if n, err := db.Append(key3, []byte("Hello")); err != nil {
t.Fatal(err)
} else if n != 5 {
t.Fatal(n)
}
if n, err := db.Append(key3, []byte(" World")); err != nil {
t.Fatal(err)
} else if n != 11 {
t.Fatal(n)
}
if n, err := db.StrLen(key3); err != nil {
t.Fatal(err)
} else if n != 11 {
t.Fatal(n)
}
if v, err := db.GetRange(key3, 0, 4); err != nil {
t.Fatal(err)
} else if string(v) != "Hello" {
t.Fatal(string(v))
}
if v, err := db.GetRange(key3, 0, -1); err != nil {
t.Fatal(err)
} else if string(v) != "Hello World" {
t.Fatal(string(v))
}
if v, err := db.GetRange(key3, -5, -1); err != nil {
t.Fatal(err)
} else if string(v) != "World" {
t.Fatal(string(v))
}
if n, err := db.SetRange(key3, 6, []byte("Redis")); err != nil {
t.Fatal(err)
} else if n != 11 {
t.Fatal(n)
}
if v, err := db.Get(key3); err != nil {
t.Fatal(err)
} else if string(v) != "Hello Redis" {
t.Fatal(string(v))
}
key4 := []byte("testdb_kv_range_none")
if n, err := db.SetRange(key4, 6, []byte("Redis")); err != nil {
t.Fatal(err)
} else if n != 11 {
t.Fatal(n)
}
} }
func TestKVPersist(t *testing.T) { func TestKVPersist(t *testing.T) {