mirror of https://github.com/ledisdb/ledisdb.git
parent
b5c78640aa
commit
926d082787
125
ledis/t_kv.go
125
ledis/t_kv.go
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue