github.com/hdt3213/godis@v1.2.9/aof/marshal.go (about) 1 package aof 2 3 import ( 4 "github.com/hdt3213/godis/datastruct/dict" 5 List "github.com/hdt3213/godis/datastruct/list" 6 "github.com/hdt3213/godis/datastruct/set" 7 SortedSet "github.com/hdt3213/godis/datastruct/sortedset" 8 "github.com/hdt3213/godis/interface/database" 9 "github.com/hdt3213/godis/redis/protocol" 10 "strconv" 11 "time" 12 ) 13 14 // EntityToCmd serialize data entity to redis command 15 func EntityToCmd(key string, entity *database.DataEntity) *protocol.MultiBulkReply { 16 if entity == nil { 17 return nil 18 } 19 var cmd *protocol.MultiBulkReply 20 switch val := entity.Data.(type) { 21 case []byte: 22 cmd = stringToCmd(key, val) 23 case List.List: 24 cmd = listToCmd(key, val) 25 case *set.Set: 26 cmd = setToCmd(key, val) 27 case dict.Dict: 28 cmd = hashToCmd(key, val) 29 case *SortedSet.SortedSet: 30 cmd = zSetToCmd(key, val) 31 } 32 return cmd 33 } 34 35 var setCmd = []byte("SET") 36 37 func stringToCmd(key string, bytes []byte) *protocol.MultiBulkReply { 38 args := make([][]byte, 3) 39 args[0] = setCmd 40 args[1] = []byte(key) 41 args[2] = bytes 42 return protocol.MakeMultiBulkReply(args) 43 } 44 45 var rPushAllCmd = []byte("RPUSH") 46 47 func listToCmd(key string, list List.List) *protocol.MultiBulkReply { 48 args := make([][]byte, 2+list.Len()) 49 args[0] = rPushAllCmd 50 args[1] = []byte(key) 51 list.ForEach(func(i int, val interface{}) bool { 52 bytes, _ := val.([]byte) 53 args[2+i] = bytes 54 return true 55 }) 56 return protocol.MakeMultiBulkReply(args) 57 } 58 59 var sAddCmd = []byte("SADD") 60 61 func setToCmd(key string, set *set.Set) *protocol.MultiBulkReply { 62 args := make([][]byte, 2+set.Len()) 63 args[0] = sAddCmd 64 args[1] = []byte(key) 65 i := 0 66 set.ForEach(func(val string) bool { 67 args[2+i] = []byte(val) 68 i++ 69 return true 70 }) 71 return protocol.MakeMultiBulkReply(args) 72 } 73 74 var hMSetCmd = []byte("HMSET") 75 76 func hashToCmd(key string, hash dict.Dict) *protocol.MultiBulkReply { 77 args := make([][]byte, 2+hash.Len()*2) 78 args[0] = hMSetCmd 79 args[1] = []byte(key) 80 i := 0 81 hash.ForEach(func(field string, val interface{}) bool { 82 bytes, _ := val.([]byte) 83 args[2+i*2] = []byte(field) 84 args[3+i*2] = bytes 85 i++ 86 return true 87 }) 88 return protocol.MakeMultiBulkReply(args) 89 } 90 91 var zAddCmd = []byte("ZADD") 92 93 func zSetToCmd(key string, zset *SortedSet.SortedSet) *protocol.MultiBulkReply { 94 args := make([][]byte, 2+zset.Len()*2) 95 args[0] = zAddCmd 96 args[1] = []byte(key) 97 i := 0 98 zset.ForEach(int64(0), int64(zset.Len()), true, func(element *SortedSet.Element) bool { 99 value := strconv.FormatFloat(element.Score, 'f', -1, 64) 100 args[2+i*2] = []byte(value) 101 args[3+i*2] = []byte(element.Member) 102 i++ 103 return true 104 }) 105 return protocol.MakeMultiBulkReply(args) 106 } 107 108 var pExpireAtBytes = []byte("PEXPIREAT") 109 110 // MakeExpireCmd generates command line to set expiration for the given key 111 func MakeExpireCmd(key string, expireAt time.Time) *protocol.MultiBulkReply { 112 args := make([][]byte, 3) 113 args[0] = pExpireAtBytes 114 args[1] = []byte(key) 115 args[2] = []byte(strconv.FormatInt(expireAt.UnixNano()/1e6, 10)) 116 return protocol.MakeMultiBulkReply(args) 117 }