package main import ( "errors" "net" "strconv" ) func handleGet(conn net.Conn, key string) { db.mu.Lock() defer db.mu.Unlock() value, exists := db.data[key] if !exists { conn.Write(serializeRESP(nil)) return } strValue, ok := value.(string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) return } conn.Write(serializeRESP(strValue)) } func handleExists(conn net.Conn, key string) { db.mu.Lock() defer db.mu.Unlock() _, exists := db.data[key] if exists { conn.Write(serializeRESP(1)) } else { conn.Write(serializeRESP(0)) } } func handleSet(conn net.Conn, key, value string) { db.mu.Lock() defer db.mu.Unlock() db.data[key] = value conn.Write(serializeRESP(SimpleString("OK"))) } func handleDel(conn net.Conn, key string) { db.mu.Lock() defer db.mu.Unlock() _, exists := db.data[key] if exists { delete(db.data, key) conn.Write(serializeRESP(1)) } else { conn.Write(serializeRESP(0)) } } func handleIncr(conn net.Conn, key string) { db.mu.Lock() defer db.mu.Unlock() value, exists := db.data[key] if exists { strValue, ok := value.(string) if !ok { err := errors.New("value is not an integer or out of range") conn.Write(serializeRESP(err)) return } currentInt, err := strconv.Atoi(strValue) if err != nil { err := errors.New("value is not an integer or out of range") conn.Write(serializeRESP(err)) return } newValueStr := strconv.Itoa(currentInt + 1) db.data[key] = newValueStr conn.Write(serializeRESP(currentInt + 1)) } else { db.data[key] = "1" conn.Write(serializeRESP(1)) } } func handleDecr(conn net.Conn, key string) { db.mu.Lock() defer db.mu.Unlock() value, exists := db.data[key] if exists { strValue, ok := value.(string) if !ok { err := errors.New("value is not an integer or out of range") conn.Write(serializeRESP(err)) return } currentInt, err := strconv.Atoi(strValue) if err != nil { err := errors.New("value is not an integer or out of range") conn.Write(serializeRESP(err)) return } newValueStr := strconv.Itoa(currentInt - 1) db.data[key] = newValueStr conn.Write(serializeRESP(currentInt - 1)) } else { db.data[key] = "-1" conn.Write(serializeRESP(-1)) } } func handlePing(conn net.Conn) { conn.Write(serializeRESP(SimpleString("PONG"))) } func handleFlushall(conn net.Conn) { db.mu.Lock() defer db.mu.Unlock() db.data = make(map[string]any) conn.Write(serializeRESP(SimpleString("OK"))) } func handleRpush(conn net.Conn, args []string) { key := args[1] newItems := args[2:] db.mu.Lock() defer db.mu.Unlock() var list []string existingValue, exists := db.data[key] if exists { var ok bool list, ok = existingValue.([]string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) return } } else { list = []string{} } list = append(list, newItems...) db.data[key] = list conn.Write(serializeRESP(len(list))) } 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(serializeRESP([]string{})) return } typedList, ok := value.([]string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) 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(serializeRESP([]string{})) return } resultList := typedList[start : stop+1] conn.Write(serializeRESP(resultList)) } func handleLpop(conn net.Conn, key string){ db.mu.Lock() defer db.mu.Unlock() value, exists := db.data[key] if !exists { conn.Write(serializeRESP(nil)) return } typedList, ok := value.([]string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) return } if len(typedList) == 0 { conn.Write(serializeRESP(nil)) return } item := typedList[0] newList := typedList[1:] if len(newList) <= 0 { delete(db.data, key) }else{ db.data[key] = newList } conn.Write(serializeRESP(item)) } func handleRpop(conn net.Conn, key string){ db.mu.Lock() defer db.mu.Unlock() value, exists := db.data[key] if !exists { conn.Write(serializeRESP(nil)) return } typedList, ok := value.([]string) if !ok { err := errors.New("WRONGTYPE Operation against a key holding the wrong kind of value") conn.Write(serializeRESP(err)) return } if len(typedList) == 0 { conn.Write(serializeRESP(nil)) return } item := typedList[len(typedList)-1] newList := typedList[:len(typedList)-1] if len(newList) <= 0 { delete(db.data, key) }else{ db.data[key] = newList } conn.Write(serializeRESP(item)) }