aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go68
1 files changed, 54 insertions, 14 deletions
diff --git a/main.go b/main.go
index ece44a2..cedb658 100644
--- a/main.go
+++ b/main.go
@@ -6,12 +6,20 @@ import (
"net"
"os"
"strings"
+ "sync"
+ "strconv"
+ "io"
)
-var database map[string]string
+type RedisDB struct {
+ mu sync.Mutex
+ data map[string]string
+}
+
+var db RedisDB
func main() {
- database = make(map[string]string)
+ db = RedisDB{data: make(map[string]string)}
listener, err := net.Listen("tcp", ":6379")
if err != nil {
@@ -32,42 +40,74 @@ func main() {
}
func handleGet(conn net.Conn, key string) {
- value, exists := database[key]
+ db.mu.Lock()
+ value, exists := db.data[key]
+ db.mu.Unlock()
if exists {
- // Redis protocol format for a string reply
conn.Write([]byte("+" + value + "\r\n"))
} else {
- // Redis protocol format for a Nil/Null response
conn.Write([]byte("$-1\r\n"))
}
}
func handleSet(conn net.Conn, key, value string) {
- database[key] = value
+ db.mu.Lock()
+ db.data[key] = value
+ db.mu.Unlock()
conn.Write([]byte("+OK\r\n"))
}
+func parseRESP(reader *bufio.Reader) ([]string, error) {
+ line, err := reader.ReadString('\n')
+ if err != nil {
+ return nil, err
+ }
+ var args []string
+
+ argC, _ := strconv.Atoi(strings.TrimSpace(line[1:]))
+
+ for i := 0; i < argC; i++ {
+ lengthLine, err := reader.ReadString('\n')
+
+ if err != nil {
+ return nil, err
+ }
+
+ strLen, _ := strconv.Atoi(strings.TrimSpace(lengthLine[1:]))
+ buf := make([]byte, strLen)
+
+ _, err = io.ReadFull(reader, buf)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = reader.Discard(2)
+ if err != nil {
+ return nil, err
+ }
+
+ args = append(args, string(buf))
+ }
+ return args, nil
+}
func handleConnection(conn net.Conn) {
defer conn.Close()
fmt.Println("Client connected:", conn.RemoteAddr())
reader := bufio.NewReader(conn)
for {
- message, err := reader.ReadString('\n')
+ args, err := parseRESP(reader)
if err != nil {
- fmt.Println("Client disconnected:", conn.RemoteAddr())
- return
+ fmt.Println("Client disconnected or error parsing:", conn.RemoteAddr(), err)
+ return
}
- message = strings.TrimSpace(message)
-
- fmt.Printf("Received: %s\n", message)
-
- args := strings.Fields(message)
if len(args) == 0 {
continue
}
+ fmt.Printf("Parsed RESP Arguments: %v\n", args)
+
command := strings.ToUpper(args[0])
switch {