예제 #1
0
func IsMultiCmd(cmd *resp.Command) (multiKey bool, numKeys int) {
	multiKey = true
	switch cmd.Name() {
	case "MGET":
		numKeys = len(cmd.Args) - 1
	case "MSET":
		numKeys = (len(cmd.Args) - 1) / 2
	case "DEL":
		numKeys = len(cmd.Args) - 1
	default:
		multiKey = false
	}
	return
}
예제 #2
0
func NewMultiKeyCmd(cmd *resp.Command, numSubCmds int) *MultiKeyCmd {
	mc := &MultiKeyCmd{
		cmd:               cmd,
		numSubCmds:        numSubCmds,
		numPendingSubCmds: numSubCmds,
	}
	switch cmd.Name() {
	case "MGET":
		mc.cmdType = MGET
	case "MSET":
		mc.cmdType = MSET
	case "DEL":
		mc.cmdType = DEL
	default:
		panic("not multi key command")
	}
	mc.subCmdRsps = make([]*PipelineResponse, numSubCmds)
	return mc
}
예제 #3
0
func (s *Session) handleMultiKeyCmd(cmd *resp.Command, numKeys int) {
	var subCmd *resp.Command
	var err error
	mc := NewMultiKeyCmd(cmd, numKeys)
	// multi sub cmd share the same seq number
	seq := s.getNextReqSeq()
	readOnly := mc.CmdType() == MGET
	for i := 0; i < numKeys; i++ {
		switch mc.CmdType() {
		case MGET:
			subCmd, err = resp.NewCommand("GET", cmd.Value(i+1))
		case MSET:
			subCmd, err = resp.NewCommand("SET", cmd.Value(2*i+1), cmd.Value((2*i + 2)))
		case DEL:
			subCmd, err = resp.NewCommand("DEL", cmd.Value(i+1))
		}
		if err != nil {
			panic(err)
		}
		key := subCmd.Value(1)
		slot := Key2Slot(key)
		plReq := &PipelineRequest{
			cmd:       subCmd,
			readOnly:  readOnly,
			slot:      slot,
			seq:       seq,
			subSeq:    i,
			backQ:     s.backQ,
			parentCmd: mc,
			wg:        s.reqWg,
		}
		s.reqWg.Add(1)
		s.dispatcher.Schedule(plReq)
	}
}
예제 #4
0
파일: filter.go 프로젝트: bytedance/rcproxy
func CmdFlag(cmd *resp.Command) int {
	return cmdFlagMap[cmd.Name()]
}