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  }