diff options
| -rw-r--r-- | main.go | 78 |
1 files changed, 78 insertions, 0 deletions
@@ -183,6 +183,76 @@ func handleRpush(conn net.Conn, args []string) { conn.Write([]byte(":" + strconv.Itoa(len(list)) + "\r\n")) } +func handleLrange(conn net.Conn, key string, start, stop int) { + db.mu.Lock() + defer db.mu.Unlock() + + value, exists := db.data[key] + if !exists { + conn.Write([]byte("*0\r\n")) + return + } + + typedList, ok := value.([]string) + if !ok { + conn.Write([]byte("-WRONGTYPE Operation against a key holding the wrong kind of value\r\n")) + return + } + + size := len(typedList) + + if start < 0 { + start += size + if start < 0 { + start = 0 + } + } + + if stop < 0 { + stop += size + if stop < 0 { + stop = 0 + } + } + + if stop >= size { + stop = size - 1 + } + + if start > stop || start >= size { + conn.Write([]byte("*0\r\n")) + return + } + + resultList := typedList[start : stop+1] + conn.Write(serializeRESP(resultList)) +} + +func serializeRESP(v any) []byte { + switch val := v.(type) { + case string: + bulkString := fmt.Sprintf("$%d\r\n%s\r\n", len(val), val) + return []byte(bulkString) + case int: + integerString := fmt.Sprintf(":%d\r\n",val) + return []byte(integerString) + case nil: + return []byte("$-1\r\n") + case error: + errorString := fmt.Sprintf("-ERR %s\r\n",val.Error()) + return []byte(errorString) + case []string: + size := len(val) + result := []byte(fmt.Sprintf("*%d\r\n", size)) + for i := 0; i < size; i++ { + result = append(result, serializeRESP(val[i])...) + } + return result + default: + return []byte("-ERR internal server error: unknown type\r\n") + } +} + func parseRESP(reader *bufio.Reader) ([]string, error) { line, err := reader.ReadString('\n') if err != nil { @@ -276,6 +346,14 @@ func handleConnection(conn net.Conn) { handleFlushall(conn) case command == "RPUSH" && len(args) >= 3: handleRpush(conn, args) + case command == "LRANGE" && len(args) == 4: + start, err1 := strconv.Atoi(args[2]) + stop, err2 := strconv.Atoi(args[3]) + if err1 != nil || err2 != nil { + conn.Write([]byte("-ERR value is not an integer or out of range\r\n")) + break + } + handleLrange(conn, args[1], start, stop) default: conn.Write([]byte("-ERR unknown command or wrong arguments\r\n")) } |
