forked from grahamking/Key-Value-Polyglot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmemg.go
executable file
·97 lines (79 loc) · 1.6 KB
/
memg.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package main
import (
"bufio"
"flag"
"fmt"
"io"
"net"
"strconv"
"strings"
)
var (
CACHE = map[string]string{}
singleFlag = flag.Bool("single", false, "Start in single mode")
)
func main() {
flag.Parse()
listener, err := net.Listen("tcp", "127.0.0.1:11211")
if err != nil {
panic("Error listening on 11211: " + err.Error())
}
CACHE = make(map[string]string)
if *singleFlag {
netconn, err := listener.Accept()
if err != nil {
panic("Accept error: " + err.Error())
}
handleConn(netconn)
} else {
for {
netconn, err := listener.Accept()
if err != nil {
panic("Accept error: " + err.Error())
}
go handleConn(netconn)
}
}
}
/*
* Networking
*/
func handleConn(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
for {
// Fetch
content, err := reader.ReadString('\n')
if err == io.EOF {
break
} else if err != nil {
fmt.Println(err)
return
}
content = content[:len(content)-2] // Chop \r\n
// Handle
parts := strings.Split(content, " ")
cmd := parts[0]
switch cmd {
case "get":
key := parts[1]
val, ok := CACHE[key]
if ok {
length := strconv.Itoa(len(val))
conn.Write([]uint8("VALUE " + key + " 0 " + length + "\r\n"))
conn.Write([]uint8(val + "\r\n"))
}
conn.Write([]uint8("END\r\n"))
case "set":
key := parts[1]
//exp := parts[2]
//flags := parts[3]
length, _ := strconv.Atoi(parts[4])
// Really we should read exactly 'length' bytes + \r\n
val := make([]byte, length)
reader.Read(val)
CACHE[key] = string(val)
conn.Write([]uint8("STORED\r\n"))
}
}
}