// 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) }
func errArguments(format string, v ...interface{}) error { err := errors.Errorf(format, v...) log.DebugErrorf(err, "call rpdb function with invalid arguments") return err }