Beispiel #1
0
func (cmd *cmdDecode) decoderMain(ipipe <-chan *rdb.BinEntry, opipe chan<- string) {
	toText := func(p []byte) string {
		var b bytes.Buffer
		for _, c := range p {
			switch {
			case c >= '#' && c <= '~':
				b.WriteByte(c)
			default:
				b.WriteByte('.')
			}
		}
		return b.String()
	}
	toBase64 := func(p []byte) string {
		return base64.StdEncoding.EncodeToString(p)
	}
	toJson := func(o interface{}) string {
		b, err := json.Marshal(o)
		if err != nil {
			log.PanicError(err, "encode to json failed")
		}
		return string(b)
	}
	for e := range ipipe {
		o, err := rdb.DecodeDump(e.Value)
		if err != nil {
			log.PanicError(err, "decode failed")
		}
		var b bytes.Buffer
		switch obj := o.(type) {
		default:
			log.Panicf("unknown object %v", o)
		case rdb.String:
			o := &struct {
				DB       uint32 `json:"db"`
				Type     string `json:"type"`
				ExpireAt uint64 `json:"expireat"`
				Key      string `json:"key"`
				Key64    string `json:"key64"`
				Value64  string `json:"value64"`
			}{
				e.DB, "string", e.ExpireAt, toText(e.Key), toBase64(e.Key),
				toBase64(obj),
			}
			fmt.Fprintf(&b, "%s\n", toJson(o))
		case rdb.List:
			for i, ele := range obj {
				o := &struct {
					DB       uint32 `json:"db"`
					Type     string `json:"type"`
					ExpireAt uint64 `json:"expireat"`
					Key      string `json:"key"`
					Key64    string `json:"key64"`
					Index    int    `json:"index"`
					Value64  string `json:"value64"`
				}{
					e.DB, "list", e.ExpireAt, toText(e.Key), toBase64(e.Key),
					i, toBase64(ele),
				}
				fmt.Fprintf(&b, "%s\n", toJson(o))
			}
		case rdb.Hash:
			for _, ele := range obj {
				o := &struct {
					DB       uint32 `json:"db"`
					Type     string `json:"type"`
					ExpireAt uint64 `json:"expireat"`
					Key      string `json:"key"`
					Key64    string `json:"key64"`
					Field    string `json:"field"`
					Field64  string `json:"field64"`
					Value64  string `json:"value64"`
				}{
					e.DB, "hash", e.ExpireAt, toText(e.Key), toBase64(e.Key),
					toText(ele.Field), toBase64(ele.Field), toBase64(ele.Value),
				}
				fmt.Fprintf(&b, "%s\n", toJson(o))
			}
		case rdb.Set:
			for _, mem := range obj {
				o := &struct {
					DB       uint32 `json:"db"`
					Type     string `json:"type"`
					ExpireAt uint64 `json:"expireat"`
					Key      string `json:"key"`
					Key64    string `json:"key64"`
					Member   string `json:"member"`
					Member64 string `json:"member64"`
				}{
					e.DB, "set", e.ExpireAt, toText(e.Key), toBase64(e.Key),
					toText(mem), toBase64(mem),
				}
				fmt.Fprintf(&b, "%s\n", toJson(o))
			}
		case rdb.ZSet:
			for _, ele := range obj {
				o := &struct {
					DB       uint32  `json:"db"`
					Type     string  `json:"type"`
					ExpireAt uint64  `json:"expireat"`
					Key      string  `json:"key"`
					Key64    string  `json:"key64"`
					Member   string  `json:"member"`
					Member64 string  `json:"member64"`
					Score    float64 `json:"score"`
				}{
					e.DB, "zset", e.ExpireAt, toText(e.Key), toBase64(e.Key),
					toText(ele.Member), toBase64(ele.Member), ele.Score,
				}
				fmt.Fprintf(&b, "%s\n", toJson(o))
			}
		}
		cmd.nentry.Incr()
		opipe <- b.String()
	}
}
Beispiel #2
0
func restoreRdbEntry(c redigo.Conn, e *rdb.BinEntry) {
	var ttlms uint64
	if e.ExpireAt != 0 {
		now := uint64(time.Now().Add(args.shift).UnixNano())
		now /= uint64(time.Millisecond)
		if now >= e.ExpireAt {
			ttlms = 1
		} else {
			ttlms = e.ExpireAt - now
		}
	}

	toText := func(p []byte) string {
		var b bytes.Buffer
		for _, c := range p {
			switch {
			case c >= '#' && c <= '~':
				b.WriteByte(c)
			default:
				b.WriteByte('.')
			}
		}
		return b.String()
	}

	if aggregateKey(e.Key) {
		log.Infof("Aggregate key %s", e.Key)
		o, err := rdb.DecodeDump(e.Value)
		if err != nil {
			log.PanicError(err, "decode failed")
		}
		switch obj := o.(type) {
		default:
			log.Panicf("unknown object %v", o)
		case rdb.List:
			for _, ele := range obj {
				_, err := c.Do(aggregateCmd, aggregateTarget, toText(ele))
				if err != nil {
					log.PanicError(err, "aggregate error")
				}
			}
		case rdb.Set:
			for _, ele := range obj {
				_, err := c.Do(aggregateCmd, aggregateTarget, toText(ele))
				if err != nil {
					log.PanicError(err, "aggregate error")
				}
			}
		}
	}

	if set2sortedKey(e.Key) {
		o, err := rdb.DecodeDump(e.Value)
		if err != nil {
			log.PanicError(err, "decode failed")
		}
		switch obj := o.(type) {
		default:
			log.Panicf("set2sorted key %s type is not set err", e.Key)
			log.Panicf("unknown object %v", o)
		case rdb.Set:
			for _, ele := range obj {
				_, err := c.Do("zadd", e.Key, 1, toText(ele))
				if err != nil {
					log.PanicErrorf(err, "set2sorted zadd %s 1 %s", e.Key, toText(ele))
				}
			}
		}
		return
	}

	if sorted2setKey(e.Key) {
		o, err := rdb.DecodeDump(e.Value)
		if err != nil {
			log.PanicError(err, "decode failed")
		}
		switch obj := o.(type) {
		default:
			log.Panicf("sorted2set key %s type is not sorted set err", e.Key)
		case rdb.ZSet:
			for _, ele := range obj {
				_, err := c.Do("sadd", e.Key, toText(ele.Member))
				if err != nil {
					log.PanicErrorf(err, "sorted2set sadd %s %s", e.Key, toText(ele.Member))
				}
			}
		}
		return
	}

	if (restoreCmd == "del") || (restoreCmd == "DEL") {
		_, err := redigo.String(c.Do(restoreCmd, e.Key))
		if err != nil {
			log.Warnf("delete key: '%s'", e.Key)
		}
	} else {
		s, err := redigo.String(c.Do(restoreCmd, e.Key, ttlms, e.Value))

		if err != nil {
			log.Warnf("restore error, when '%s' '%s'", restoreCmd, e.Key)
			//log.PanicError(err, "restore command error")
		}
		if s != "OK" {
			//log.Panicf("restore command response = '%s', should be 'OK'", s)
			log.Warnf("restore command response = '%s', should be 'OK'", s)
		}
	}
}