Skip to content

Commit

Permalink
Add SetRange command
Browse files Browse the repository at this point in the history
  • Loading branch information
diiyw committed May 10, 2024
1 parent d102e29 commit 80940d8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
18 changes: 17 additions & 1 deletion ds/str/str.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (s *String) Set(v []byte) {
s.V = v
}

// GetSet
// GetSet set the value and return the old value
func (s *String) GetSet(v []byte) []byte {
old := s.V
s.V = v
Expand Down Expand Up @@ -217,6 +217,22 @@ func (s *String) Strlen() int64 {
return int64(len(s.V))
}

// SetRange sets the value at the offset
func (s *String) SetRange(offset int64, data []byte) int64 {
if offset < 0 {
return 0
}
vLen := int64(len(s.V))
if offset > vLen {
s.V = append(s.V, make([]byte, offset-vLen...)...)

Check failure on line 227 in ds/str/str.go

View workflow job for this annotation

GitHub Actions / unit-test-linux

invalid operation: invalid use of ... with built-in make

Check failure on line 227 in ds/str/str.go

View workflow job for this annotation

GitHub Actions / build

invalid operation: invalid use of ... with built-in make
}
if offset+vLen > vLen {
s.V = append(s.V, make([]byte, offset+vLen-vLen...)...)

Check failure on line 230 in ds/str/str.go

View workflow job for this annotation

GitHub Actions / unit-test-linux

invalid operation: invalid use of ... with built-in make

Check failure on line 230 in ds/str/str.go

View workflow job for this annotation

GitHub Actions / build

invalid operation: invalid use of ... with built-in make
}
copy(s.V[offset:], data)
return int64(len(s.V))
}

// GetValue the string to bytes
func (s *String) GetValue() []byte {
return s.V
Expand Down
19 changes: 19 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ func getCommand(name string) func(n *Nodis, conn *redis.Conn, cmd redis.Command)
return getSet
case "MGET":
return mGet
case "SETRANGE":
return setRange
case "GETRANGE":
return getRange
case "STRLEN":
Expand Down Expand Up @@ -879,6 +881,23 @@ func mGet(n *Nodis, conn *redis.Conn, cmd redis.Command) {
})
}

func setRange(n *Nodis, conn *redis.Conn, cmd redis.Command) {
if len(cmd.Args) < 3 {
conn.WriteError("SETRANGE requires at least three arguments")
return
}
key := cmd.Args[0]
offset, err := strconv.ParseInt(cmd.Args[1], 10, 64)
if err != nil {
conn.WriteError("ERR offset value is not an integer or out of range")
return
}
value := []byte(cmd.Args[2])
execCommand(conn, func() {
conn.WriteInteger(n.SetRange(key, offset, value))
})
}

func getRange(n *Nodis, conn *redis.Conn, cmd redis.Command) {
if len(cmd.Args) < 3 {
conn.WriteError("GETRANGE requires at least three arguments")
Expand Down
13 changes: 13 additions & 0 deletions str.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,19 @@ func (n *Nodis) StrLen(key string) int64 {
return v
}

// SetRange overwrite part of a string at key starting at the specified offset
func (n *Nodis) SetRange(key string, offset int64, value []byte) int64 {
var v int64
_ = n.exec(func(tx *Tx) error {
meta := tx.writeKey(key, n.newStr)
k := meta.ds.(*str.String)
v = k.SetRange(offset, value)
n.notify(pb.NewOp(pb.OpType_Set, key).Value(k.Get()))
return nil
})
return v
}

// MSet sets the given keys to their respective values
func (n *Nodis) MSet(pairs ...string) {
if len(pairs)%2 != 0 {
Expand Down

0 comments on commit 80940d8

Please sign in to comment.