forked from CodisLabs/codis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mapper.go
104 lines (90 loc) · 2.35 KB
/
mapper.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
98
99
100
101
102
103
104
// Copyright 2014 Wandoujia Inc. All Rights Reserved.
// Licensed under the MIT (MIT-LICENSE.txt) license.
package router
import (
"bytes"
"hash/crc32"
"strings"
"github.com/wandoulabs/codis/pkg/proxy/redis"
"github.com/wandoulabs/codis/pkg/utils/errors"
)
var charmap [128]byte
func init() {
for i := 0; i < len(charmap); i++ {
c := byte(i)
if c >= 'a' && c <= 'z' {
c = c - 'a' + 'A'
}
charmap[i] = c
}
}
var (
blacklist = make(map[string]bool)
)
func init() {
for _, s := range []string{
"KEYS", "MOVE", "OBJECT", "RENAME", "RENAMENX", "SCAN", "BITOP", "MSETNX", "MIGRATE", "RESTORE",
"BLPOP", "BRPOP", "BRPOPLPUSH", "PSUBSCRIBE", "PUBLISH", "PUNSUBSCRIBE", "SUBSCRIBE", "RANDOMKEY",
"UNSUBSCRIBE", "DISCARD", "EXEC", "MULTI", "UNWATCH", "WATCH", "SCRIPT",
"BGREWRITEAOF", "BGSAVE", "CLIENT", "CONFIG", "DBSIZE", "DEBUG", "FLUSHALL", "FLUSHDB",
"LASTSAVE", "MONITOR", "SAVE", "SHUTDOWN", "SLAVEOF", "SLOWLOG", "SYNC", "TIME",
"SLOTSINFO", "SLOTSDEL", "SLOTSMGRTSLOT", "SLOTSMGRTONE", "SLOTSMGRTTAGSLOT", "SLOTSMGRTTAGONE", "SLOTSCHECK",
} {
blacklist[s] = true
}
}
func isNotAllowed(opstr string) bool {
return blacklist[opstr]
}
var (
ErrBadRespType = errors.New("bad resp type for command")
ErrBadOpStrLen = errors.New("bad command length, too short or too long")
)
func getOpStr(resp *redis.Resp) (string, error) {
if !resp.IsArray() || len(resp.Array) == 0 {
return "", ErrBadRespType
}
for _, r := range resp.Array {
if r.IsBulkBytes() {
continue
}
return "", ErrBadRespType
}
var upper [64]byte
var op = resp.Array[0].Value
if len(op) == 0 || len(op) > len(upper) {
return "", ErrBadOpStrLen
}
for i := 0; i < len(op); i++ {
c := uint8(op[i])
if k := int(c); k < len(charmap) {
upper[i] = charmap[k]
} else {
return strings.ToUpper(string(op)), nil
}
}
return string(upper[:len(op)]), nil
}
func hashSlot(key []byte) int {
const (
TagBeg = '{'
TagEnd = '}'
)
if beg := bytes.IndexByte(key, TagBeg); beg >= 0 {
if end := bytes.IndexByte(key[beg+1:], TagEnd); end >= 0 {
key = key[beg+1 : beg+1+end]
}
}
return int(crc32.ChecksumIEEE(key) % MaxSlotNum)
}
func getHashKey(resp *redis.Resp, opstr string) []byte {
var index = 1
switch opstr {
case "ZINTERSTORE", "ZUNIONSTORE", "EVAL", "EVALSHA":
index = 3
}
if index < len(resp.Array) {
return resp.Array[index].Value
}
return nil
}