Beispiel #1
0
// SLOTSRESTORE key ttlms value [key ttlms value ...]
func (b *Rpdb) SlotsRestore(db uint32, args ...interface{}) error {
	if len(args) == 0 || len(args)%3 != 0 {
		return errArguments("len(args) = %d, expect != 0 && mod 3 = 0", len(args))
	}

	objs := make([]*rdb.ObjEntry, len(args)/3)
	for i := 0; i < len(objs); i++ {
		var key, value []byte
		var ttlms int64
		for j, ref := range []interface{}{&key, &ttlms, &value} {
			if err := parseArgument(args[i*3+j], ref); err != nil {
				return errArguments("parse args[%d] failed, %s", i*3+j, err)
			}
		}
		expireat := uint64(0)
		if ttlms != 0 {
			if v, ok := TTLmsToExpireAt(ttlms); ok && v > 0 {
				expireat = v
			} else {
				return errArguments("parse args[%d] ttlms = %d", i*3+1, ttlms)
			}
		}
		obj, err := rdb.DecodeDump(value)
		if err != nil {
			return errArguments("decode args[%d] failed, %s", i*3+2, err)
		}
		objs[i] = &rdb.ObjEntry{
			DB:       db,
			Key:      key,
			ExpireAt: expireat,
			Value:    obj,
		}
	}

	if err := b.acquire(); err != nil {
		return err
	}
	defer b.release()

	ms := &markSet{}
	bt := store.NewBatch()
	for i := len(objs) - 1; i >= 0; i-- {
		e := objs[i]
		if ms.Has(e.Key) {
			log.Debugf("[%d] restore batch, db = %d, key = %v, ignore", i, e.DB, e.Key)
			continue
		} else {
			log.Debugf("[%d] restore batch, db = %d, key = %v", i, e.DB, e.Key)
		}
		if err := b.restore(bt, e.DB, e.Key, e.ExpireAt, e.Value); err != nil {
			log.DebugErrorf(err, "restore object failed, db = %d, key = %v", e.DB, e.Key)
			return err
		}
		ms.Set(e.Key)
	}
	fw := &Forward{DB: db, Op: "SlotsRestore", Args: args}
	return b.commit(bt, fw)
}
Beispiel #2
0
func errArguments(format string, v ...interface{}) error {
	err := errors.Errorf(format, v...)
	log.DebugErrorf(err, "call rpdb function with invalid arguments")
	return err
}