func (o *setRow) getMembers(r rpdbReader, count int64) ([][]byte, error) { it := r.getIterator() defer r.putIterator(it) var members [][]byte for pfx := it.SeekTo(o.DataKeyPrefix()); count > 0 && it.Valid(); it.Next() { key := it.Key() if !bytes.HasPrefix(key, pfx) { break } sfx := key[len(pfx):] if err := o.ParseDataKeySuffix(sfx); err != nil { return nil, err } if err := o.ParseDataValue(it.Value()); err != nil { return nil, err } if len(o.Member) == 0 { return nil, errors.Errorf("len(member) = %d", len(o.Member)) } members = append(members, o.Member) count-- } if err := it.Error(); err != nil { return nil, err } if len(members) == 0 { return nil, errors.Errorf("len(members) = %d, set.size = %d", len(members), o.Size) } return members, nil }
func (o *hashRow) getAllValues(r rpdbReader) ([][]byte, error) { it := r.getIterator() defer r.putIterator(it) var values [][]byte for pfx := it.SeekTo(o.DataKeyPrefix()); it.Valid(); it.Next() { key := it.Key() if !bytes.HasPrefix(key, pfx) { break } if err := o.ParseDataValue(it.Value()); err != nil { return nil, err } if len(o.Value) == 0 { return nil, errors.Errorf("len(value) = %d", len(o.Value)) } values = append(values, o.Value) } if err := it.Error(); err != nil { return nil, err } if len(values) == 0 || int64(len(values)) != o.Size { return nil, errors.Errorf("len(values) = %d, hash.size = %d", len(values), o.Size) } return values, nil }
func ParseFloat64(i interface{}) (float64, error) { if v, ok := Num64(i); ok { switch x := v.(type) { case int64: return float64(x), nil case uint64: return float64(x), nil case float64: switch { case math.IsNaN(x): return 0, errors.Errorf("parse nan float64") case math.IsInf(x, 0): return 0, errors.Errorf("parse inf float64") } return float64(x), nil default: return 0, errors.Errorf("parse float64 from unknown num64") } } else { var s string switch x := i.(type) { case nil: return 0, errors.Errorf("parse float64 from nil") case string: s = x case []byte: s = string(x) default: return 0, errors.Errorf("parse float64 from <%s>", reflect.TypeOf(i)) } f, err := strconv.ParseFloat(s, 64) return f, errors.Trace(err) } }
func decodeRawBytes(r *BufReader, err error, refs ...interface{}) error { if err != nil { return err } if len(refs) == 0 { if r.Len() != 0 { return errors.Trace(ErrNotMatched) } return nil } for _, i := range refs { switch x := i.(type) { case byte: if v, err := r.ReadByte(); err != nil { return err } else if v != x { return errors.Errorf("read byte %d, expect %d", v, x) } case ObjectCode: if v, err := r.ReadByte(); err != nil { return err } else if v != byte(x) { return errors.Errorf("read code [%s], expect [%s]", ObjectCode(v), x) } case *[]byte: p, err := r.ReadVarbytes() if err != nil { return err } *x = p case *uint32: v, err := r.ReadUvarint() if err != nil { return err } *x = uint32(v) case *uint64: v, err := r.ReadUvarint() if err != nil { return err } *x = v case *int64: v, err := r.ReadVarint() if err != nil { return err } *x = v case *float64: v, err := r.ReadFloat64() if err != nil { return err } *x = v default: log.Panicf("unsupported type in row value: %+v", x) } } return nil }
func (o *hashRow) getAllFields(r rpdbReader) ([][]byte, error) { it := r.getIterator() defer r.putIterator(it) var fields [][]byte for pfx := it.SeekTo(o.DataKeyPrefix()); it.Valid(); it.Next() { key := it.Key() if !bytes.HasPrefix(key, pfx) { break } sfx := key[len(pfx):] if err := o.ParseDataKeySuffix(sfx); err != nil { return nil, err } if len(o.Field) == 0 { return nil, errors.Errorf("len(field) = %d", len(o.Field)) } fields = append(fields, o.Field) } if err := it.Error(); err != nil { return nil, err } if len(fields) == 0 || int64(len(fields)) != o.Size { return nil, errors.Errorf("len(fields) = %d, hash.size = %d", len(fields), o.Size) } return fields, nil }
func parseArgument(arg interface{}, ref interface{}) error { switch x := ref.(type) { default: return errors.Errorf("unsupported type, %v", reflect.TypeOf(x)) case *int64: v, err := ParseInt(arg) if err != nil { return errors.Errorf("expect %v, %s", reflect.TypeOf(*x), err.Error()) } *x = v case *uint32: v, err := ParseUint(arg) if err != nil { return errors.Errorf("expect %v, %s", reflect.TypeOf(*x), err.Error()) } else if v > math.MaxUint32 { return errors.Errorf("expect %v, but got %d", reflect.TypeOf(*x), v) } *x = uint32(v) case *uint64: v, err := ParseUint(arg) if err != nil { return errors.Errorf("expect %v, %s", reflect.TypeOf(*x), err.Error()) } *x = v case *float64: v, err := ParseFloat(arg) if err != nil { return errors.Errorf("expect %v, %s", reflect.TypeOf(*x), err.Error()) } *x = v case *[]byte: switch y := arg.(type) { case []byte: *x = y case string: *x = []byte(y) default: return errors.Errorf("expect %v, but got %v", reflect.TypeOf(*x), reflect.TypeOf(y)) } if len(*x) == 0 { return errors.Errorf("byte slice length = 0") } case *string: switch y := arg.(type) { case []byte: *x = string(y) case string: *x = y default: return errors.Errorf("expect %v, but got %v", reflect.TypeOf(*x), reflect.TypeOf(y)) } if len(*x) == 0 { return errors.Errorf("string length = 0") } } return nil }
func (l *Loader) Header() error { header := make([]byte, 9) if err := l.readFull(header); err != nil { return err } if !bytes.Equal(header[:5], []byte("REDIS")) { return errors.Errorf("verify magic string, invalid file format") } if version, err := strconv.ParseInt(string(header[5:]), 10, 64); err != nil { return errors.Trace(err) } else if version <= 0 || version > Version { return errors.Errorf("verify version, invalid RDB version number %d", version) } return nil }
func (o *setRow) loadObjectValue(r rpdbReader) (interface{}, error) { it := r.getIterator() defer r.putIterator(it) set := make([][]byte, 0, o.Size) for pfx := it.SeekTo(o.DataKeyPrefix()); it.Valid(); it.Next() { key := it.Key() if !bytes.HasPrefix(key, pfx) { break } sfx := key[len(pfx):] if err := o.ParseDataKeySuffix(sfx); err != nil { return nil, err } if err := o.ParseDataValue(it.Value()); err != nil { return nil, err } set = append(set, o.Member) } if err := it.Error(); err != nil { return nil, err } if o.Size == 0 || int64(len(set)) != o.Size { return nil, errors.Errorf("len(set) = %d, set.size = %d", len(set), o.Size) } return rdb.Set(set), nil }
func (c *conn) DoMustOK(cmd *redis.Array, timeout time.Duration) error { if rsp, err := c.Do(cmd, timeout); err != nil { return err } else { s, ok := rsp.(*redis.String) if ok { if s.Value == "OK" { return nil } c.err = errors.Errorf("not OK, got %s", s.Value) } else { c.err = errors.Errorf("not string response, got %v", rsp.Type()) } return c.err } }
func (e *Encoder) EncodeObject(db uint32, key []byte, expireat uint64, obj interface{}) error { o, ok := obj.(objectEncoder) if !ok { return errors.Errorf("unsupported object type") } if e.db == -1 || uint32(e.db) != db { e.db = int64(db) if err := e.enc.EncodeDatabase(int(db)); err != nil { return errors.Trace(err) } } if expireat != 0 { if err := e.enc.EncodeExpiry(expireat); err != nil { return errors.Trace(err) } } if err := o.encodeType(e.enc); err != nil { return err } if err := e.enc.EncodeString(key); err != nil { return errors.Trace(err) } if err := o.encodeValue(e.enc); err != nil { return err } return nil }
func (e *encoder) encodeResp(r Resp) error { switch x := r.(type) { default: return errors.Errorf("bad resp type <%s>", reflect.TypeOf(r)) case *String: if err := e.encodeType(typeString); err != nil { return err } return e.encodeText(x.Value) case *Error: if err := e.encodeType(typeError); err != nil { return err } return e.encodeText(x.Value) case *Int: if err := e.encodeType(typeInt); err != nil { return err } return e.encodeInt(x.Value) case *BulkBytes: if err := e.encodeType(typeBulkBytes); err != nil { return err } return e.encodeBulkBytes(x.Value) case *Array: if err := e.encodeType(typeArray); err != nil { return err } return e.encodeArray(x.Value) } }
func (r *rdbReader) readString() ([]byte, error) { length, encoded, err := r.readEncodedLength() if err != nil { return nil, err } if !encoded { return r.readBytes(int(length)) } switch t := uint8(length); t { default: return nil, errors.Errorf("invalid encoded-string %02x", t) case rdbEncInt8: i, err := r.readInt8() return []byte(strconv.FormatInt(int64(i), 10)), err case rdbEncInt16: i, err := r.readInt16() return []byte(strconv.FormatInt(int64(i), 10)), err case rdbEncInt32: i, err := r.readInt32() return []byte(strconv.FormatInt(int64(i), 10)), err case rdbEncLZF: var inlen, outlen uint32 if inlen, err = r.readLength(); err != nil { return nil, err } if outlen, err = r.readLength(); err != nil { return nil, err } if in, err := r.readBytes(int(inlen)); err != nil { return nil, err } else { return lzfDecompress(in, int(outlen)) } } }
func (o *hashRow) loadObjectValue(r rpdbReader) (interface{}, error) { it := r.getIterator() defer r.putIterator(it) hash := make([]*rdb.HashElement, 0, o.Size) for pfx := it.SeekTo(o.DataKeyPrefix()); it.Valid(); it.Next() { key := it.Key() if !bytes.HasPrefix(key, pfx) { break } sfx := key[len(pfx):] if err := o.ParseDataKeySuffix(sfx); err != nil { return nil, err } if err := o.ParseDataValue(it.Value()); err != nil { return nil, err } hash = append(hash, &rdb.HashElement{Field: o.Field, Value: o.Value}) } if err := it.Error(); err != nil { return nil, err } if o.Size == 0 || int64(len(hash)) != o.Size { return nil, errors.Errorf("len(hash) = %d, hash.size = %d", len(hash), o.Size) } return rdb.Hash(hash), nil }
func (c *conn) ping() error { deadline := time.Now().Add(time.Second * 5) if err := c.nc.SetDeadline(deadline); err != nil { return errors.Trace(err) } if _, err := c.w.WriteString("*1\r\n$4\r\nping\r\n"); err != nil { return errors.Trace(err) } if err := c.w.Flush(); err != nil { return errors.Trace(err) } var rsp string for !strings.HasSuffix(rsp, "\r\n") { b := []byte{0} if _, err := c.r.Read(b); err != nil { return errors.Trace(err) } if len(rsp) == 0 && b[0] == '\n' { continue } rsp += string(b) } rsp = rsp[:len(rsp)-2] if strings.ToLower(rsp) != "+pong" { return errors.Errorf("invalid response of command ping: %s", rsp) } else { return nil } }
func (r *rdbReader) readLength() (uint32, error) { length, encoded, err := r.readEncodedLength() if err == nil && encoded { err = errors.Errorf("encoded-length") } return length, err }
func (r *rdbReader) readObjectValue(t byte) ([]byte, error) { var b bytes.Buffer r = newRdbReader(io.TeeReader(r, &b)) switch t { default: return nil, errors.Errorf("unknown object-type %02x", t) case rdbTypeHashZipmap: fallthrough case rdbTypeListZiplist: fallthrough case rdbTypeSetIntset: fallthrough case rdbTypeZSetZiplist: fallthrough case rdbTypeHashZiplist: fallthrough case rdbTypeString: if _, err := r.readString(); err != nil { return nil, err } case rdbTypeList, rdbTypeSet: if n, err := r.readLength(); err != nil { return nil, err } else { for i := 0; i < int(n); i++ { if _, err := r.readString(); err != nil { return nil, err } } } case rdbTypeZSet: if n, err := r.readLength(); err != nil { return nil, err } else { for i := 0; i < int(n); i++ { if _, err := r.readString(); err != nil { return nil, err } if _, err := r.readFloat(); err != nil { return nil, err } } } case rdbTypeHash: if n, err := r.readLength(); err != nil { return nil, err } else { for i := 0; i < int(n); i++ { if _, err := r.readString(); err != nil { return nil, err } if _, err := r.readString(); err != nil { return nil, err } } } } return b.Bytes(), nil }
func (l *Loader) Footer() error { crc1 := l.crc.Sum64() if crc2, err := l.readUint64(); err != nil { return err } else if crc1 != crc2 { return errors.Errorf("checksum validation failed") } return nil }
func (s *Server) Dispatch(arg0 interface{}, resp Resp) (Resp, error) { if cmd, args, err := ParseArgs(resp); err != nil { return nil, err } else if f := s.t[cmd]; f == nil { return nil, errors.Errorf("unknown command '%s'", cmd) } else { return f(arg0, args...) } }
func (d *decoder) initObject(obj interface{}) { if d.err != nil { return } if d.obj != nil { d.err = errors.Errorf("invalid object, init again") } else { d.obj = obj } }
func parseInt(s string, min, max int) (int, error) { n, err := strconv.Atoi(s) if err != nil { return 0, err } if n >= min && n <= max { return n, nil } return 0, errors.Errorf("out of range [%d,%d], got %d", min, max, n) }
func AsArray(r Resp, err error) ([]Resp, error) { if err != nil { return nil, err } x, ok := r.(*Array) if ok && x != nil { return x.Value, nil } else { return nil, errors.Errorf("expect Array, but got <%s>", reflect.TypeOf(r)) } }
func AsBulkBytes(r Resp, err error) ([]byte, error) { if err != nil { return nil, err } x, ok := r.(*BulkBytes) if ok && x != nil { return x.Value, nil } else { return nil, errors.Errorf("expect BulkBytes, but got <%s>", reflect.TypeOf(r)) } }
func AsInt(r Resp, err error) (int64, error) { if err != nil { return 0, err } x, ok := r.(*Int) if ok && x != nil { return x.Value, nil } else { return 0, errors.Errorf("expect Int, but got <%s>", reflect.TypeOf(r)) } }
func (d *decoder) Sadd(key, member []byte) { if d.err != nil { return } switch s := d.obj.(type) { default: d.err = errors.Errorf("invalid object, not a set") case Set: d.obj = append(s, member) } }
func AsError(r Resp, err error) (string, error) { if err != nil { return "", err } x, ok := r.(*Error) if ok && x != nil { return x.Value, nil } else { return "", errors.Errorf("expect Error, but got <%s>", reflect.TypeOf(r)) } }
func (d *decoder) Rpush(key, value []byte) { if d.err != nil { return } switch l := d.obj.(type) { default: d.err = errors.Errorf("invalid object, not a list") case List: d.obj = append(l, value) } }
func (s *RpdbSnapshot) LoadObjCron(wait time.Duration, ncpu, step int) ([]*rdb.ObjEntry, bool, error) { if err := s.acquire(); err != nil { return nil, false, err } defer s.release() if wait <= 0 || ncpu <= 0 || step <= 0 { return nil, false, errors.Errorf("wait = %d, ncpu = %d, step = %d", wait, ncpu, step) } ctrl := make(chan int, 0) exit := make(chan int, ncpu) rets := &struct { sync.Mutex objs []*rdb.ObjEntry more bool err error }{} var wg sync.WaitGroup for i := 0; i < ncpu; i++ { wg.Add(1) go func() { defer wg.Done() objs, more, err := s.loadObjCron(ctrl, exit) rets.Lock() if len(objs) != 0 { rets.objs = append(rets.objs, objs...) } if more { rets.more = true } if rets.err == nil && err != nil { rets.err = err } rets.Unlock() }() } deadline := time.Now().Add(wait) for stop := false; !stop && step != 0; step-- { select { case ctrl <- 0: case <-exit: stop = true } if time.Now().After(deadline) { stop = true } } close(ctrl) wg.Wait() return rets.objs, rets.more, rets.err }
func session(arg0 interface{}, args [][]byte) (Session, error) { s, _ := arg0.(Session) if s == nil { return nil, errors.New("invalid session") } for i, v := range args { if len(v) == 0 { return nil, errors.Errorf("args[%d] is nil", i) } } return s, nil }
func (d *decoder) Hset(key, field, value []byte) { if d.err != nil { return } switch h := d.obj.(type) { default: d.err = errors.Errorf("invalid object, not a hashmap") case Hash: v := &HashElement{Field: field, Value: value} d.obj = append(h, v) } }
func (d *decoder) Zadd(key []byte, score float64, member []byte) { if d.err != nil { return } switch z := d.obj.(type) { default: d.err = errors.Errorf("invalid object, not a zset") case ZSet: v := &ZSetElement{Member: member, Score: score} d.obj = append(z, v) } }