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) encodeText(s string) error { if _, err := e.w.WriteString(s); err != nil { return errors.Trace(err) } if _, err := e.w.WriteString("\r\n"); err != nil { return errors.Trace(err) } return nil }
func (o Set) encodeValue(enc *rdb.Encoder) error { if err := enc.EncodeLength(uint32(len(o))); err != nil { return errors.Trace(err) } for _, e := range o { if err := enc.EncodeString(e); err != nil { return errors.Trace(err) } } return nil }
func (d *decoder) decodeText() (string, error) { b, err := d.r.ReadBytes('\n') if err != nil { return "", errors.Trace(err) } if n := len(b) - 2; n < 0 || b[n] != '\r' { return "", errors.Trace(ErrBadRespCRLFEnd) } else { return string(b[:n]), nil } }
func (p *fileBuffer) writeSome(b []byte) (int, error) { if p.f == nil { return 0, errors.Trace(io.ErrClosedPipe) } maxlen, offset := woffset(len(b), p.size, p.rpos, p.wpos) if maxlen == 0 { return 0, nil } n, err := p.f.WriteAt(b[:maxlen], int64(offset)) p.wpos += uint64(n) return n, errors.Trace(err) }
func (p *memBuffer) readSomeAt(b []byte, rpos uint64) (int, error) { if p.b == nil { return 0, errors.Trace(ErrClosedBacklog) } if rpos > p.wpos || rpos+p.size < p.wpos { return 0, errors.Trace(ErrInvalidOffset) } maxlen, offset := roffset(len(b), p.size, rpos, p.wpos) if maxlen == 0 { return 0, nil } n := copy(b, p.b[offset:offset+maxlen]) return n, nil }
func (p *fileBuffer) readSomeAt(b []byte, rpos uint64) (int, error) { if p.f == nil { return 0, errors.Trace(ErrClosedBacklog) } if rpos > p.wpos || rpos+p.size < p.wpos { return 0, errors.Trace(ErrInvalidOffset) } maxlen, offset := roffset(len(b), p.size, rpos, p.wpos) if maxlen == 0 { return 0, nil } n, err := p.f.ReadAt(b[:maxlen], int64(offset)) return n, errors.Trace(err) }
func (e *encoder) encodeBulkBytes(b []byte) error { if b == nil { return e.encodeInt(-1) } else { if err := e.encodeInt(int64(len(b))); err != nil { return err } if _, err := e.w.Write(b); err != nil { return errors.Trace(err) } if _, err := e.w.WriteString("\r\n"); err != nil { return errors.Trace(err) } return 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 authPassword(c net.Conn, passwd string) { if passwd == "" { return } _, err := c.Write(redis.MustEncodeToBytes(redis.NewCommand("auth", passwd))) if err != nil { log.PanicError(errors.Trace(err), "write auth command failed") } var b = make([]byte, 5) if _, err := io.ReadFull(c, b); err != nil { log.PanicError(errors.Trace(err), "read auth response failed") } if strings.ToUpper(string(b)) != "+OK\r\n" { log.Panic("auth failed") } }
func openSyncConn(target string, passwd string) (net.Conn, <-chan int64) { c := openNetConn(target, passwd) if _, err := c.Write(redis.MustEncodeToBytes(redis.NewCommand("sync"))); err != nil { log.PanicError(errors.Trace(err), "write sync command failed") } return c, waitRdbDump(c) }
func (d *decoder) decodeType() (respType, error) { if b, err := d.r.ReadByte(); err != nil { return 0, errors.Trace(err) } else { return respType(b), nil } }
func DecodeDump(p []byte) (interface{}, error) { d := &decoder{} if err := rdb.DecodeDump(p, 0, nil, 0, d); err != nil { return nil, errors.Trace(err) } return d.obj, d.err }
func (p *fileBuffer) rclose() error { if f := p.f; f != nil { p.f = nil defer f.Close() return errors.Trace(f.Truncate(0)) } return nil }
func Parse(s string) (int64, error) { if !BytesizeRegexp.MatchString(s) { return 0, errors.Trace(ErrBadBytesize) } subs := BytesizeRegexp.FindStringSubmatch(s) if len(subs) != 3 { return 0, errors.Trace(ErrBadBytesize) } size := int64(0) switch strings.ToUpper(string(subs[2])) { case "B", "": size = 1 case "KB", "K": size = KB case "MB", "M": size = MB case "GB", "G": size = GB case "TB", "T": size = TB case "PB", "P": size = PB default: return 0, errors.Trace(ErrBadBytesizeUnit) } text := subs[1] if digitsRegexp.MatchString(text) { n, err := strconv.ParseInt(text, 10, 64) if err != nil { return 0, errors.Trace(ErrBadBytesize) } size *= n } else { n, err := strconv.ParseFloat(text, 64) if err != nil { return 0, errors.Trace(ErrBadBytesize) } size = int64(float64(size) * n) } return size, nil }
func (d *decoder) decodeBulkBytes() ([]byte, error) { n, err := d.decodeInt() if err != nil { return nil, err } if n < -1 { return nil, errors.Trace(ErrBadRespBytesLen) } else if n == -1 { return nil, nil } b := make([]byte, n+2) if _, err := io.ReadFull(d.r, b); err != nil { return nil, errors.Trace(err) } if b[n] != '\r' || b[n+1] != '\n' { return nil, errors.Trace(ErrBadRespCRLFEnd) } return b[:n], nil }
func (p *fileBuffer) readSome(b []byte) (int, error) { if p.f == nil { return 0, errors.Trace(io.ErrClosedPipe) } maxlen, offset := roffset(len(b), p.size, p.rpos, p.wpos) if maxlen == 0 { return 0, nil } n, err := p.f.ReadAt(b[:maxlen], int64(offset)) p.rpos += uint64(n) if p.rpos == p.wpos { p.rpos = 0 p.wpos = 0 if err == nil { err = p.f.Truncate(0) } } return n, errors.Trace(err) }
func Encode(w *bufio.Writer, r Resp, flush bool) error { e := &encoder{w} if err := e.encodeResp(r); err != nil { return err } if !flush { return nil } return errors.Trace(w.Flush()) }
func (d *decoder) decodeSingleLineBulkBytesArray() (Resp, error) { b, err := d.r.ReadBytes('\n') if err != nil { return nil, errors.Trace(err) } if n := len(b) - 2; n < 0 || b[n] != '\r' { return nil, errors.Trace(ErrBadRespCRLFEnd) } else { resp := &Array{} for l, r := 0, 0; r <= n; r++ { if r == n || b[r] == ' ' { if l < r { resp.Value = append(resp.Value, &BulkBytes{b[l:r]}) } l = r + 1 } } return resp, nil } }
func (d *decoder) decodeInt() (int64, error) { b, err := d.decodeText() if err != nil { return 0, err } if n, err := strconv.ParseInt(string(b), 10, 64); err != nil { return 0, errors.Trace(err) } else { return n, nil } }
func (p *memBuffer) writeSome(b []byte) (int, error) { if p.b == nil { return 0, errors.Trace(ErrClosedBacklog) } maxlen, offset := woffset(len(b), p.size, p.wpos) if maxlen == 0 { return 0, nil } n := copy(p.b[offset:offset+maxlen], b) p.wpos += uint64(n) return n, nil }
func (bl *Backlog) DataRange() (rpos, wpos uint64, err error) { bl.mu.Lock() defer bl.mu.Unlock() if bl.store == nil { return 0, 0, errors.Trace(ErrClosedBacklog) } if bl.err != nil { return 0, 0, bl.err } rpos, wpos = bl.store.dataRange() return rpos, wpos, nil }
func (bl *Backlog) NewReader() (*Reader, error) { bl.mu.Lock() defer bl.mu.Unlock() if bl.store == nil { return nil, errors.Trace(ErrClosedBacklog) } if bl.err != nil { return nil, bl.err } _, wpos := bl.store.dataRange() return &Reader{bl: bl, seek: wpos}, nil }
func (p *pipe) WClose(err error) error { if err == nil { err = errors.Trace(io.EOF) } p.mu.Lock() defer p.mu.Unlock() if p.werr == nil { p.werr = err } p.rwait.Signal() p.wwait.Signal() return p.store.wclose() }
func (bl *Backlog) CloseWithError(err error) error { if err == nil { err = errors.Trace(ErrClosedBacklog) } bl.mu.Lock() defer bl.mu.Unlock() if bl.err != nil { bl.err = err } bl.rwait.Broadcast() if bl.store != nil { return bl.store.close() } 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 (bl *Backlog) writeSome(b []byte) (int, error) { bl.mu.Lock() defer bl.mu.Unlock() if bl.store == nil { return 0, errors.Trace(ErrClosedBacklog) } if len(b) == 0 || bl.err != nil { return 0, bl.err } n, err := bl.store.writeSome(b) if err != nil || n != 0 { bl.rwait.Broadcast() return n, err } return 0, nil }
func (p *memBuffer) readSome(b []byte) (int, error) { if p.b == nil { return 0, errors.Trace(io.ErrClosedPipe) } maxlen, offset := roffset(len(b), p.size, p.rpos, p.wpos) if maxlen == 0 { return 0, nil } n := copy(b, p.b[offset:offset+maxlen]) p.rpos += uint64(n) if p.rpos == p.wpos { p.rpos = 0 p.wpos = 0 } return n, nil }
func (bl *Backlog) readSomeAt(b []byte, rpos uint64) (int, error) { bl.mu.Lock() defer bl.mu.Unlock() if bl.store == nil { return 0, errors.Trace(ErrClosedBacklog) } if len(b) == 0 || bl.err != nil { return 0, bl.err } n, err := bl.store.readSomeAt(b, rpos) if err != nil || n != 0 { return n, err } bl.rwait.Wait() return 0, nil }
func EncodeDump(obj interface{}) ([]byte, error) { o, ok := obj.(objectEncoder) if !ok { return nil, errors.Errorf("unsupported object type") } var b bytes.Buffer enc := rdb.NewEncoder(&b) if err := o.encodeType(enc); err != nil { return nil, err } if err := o.encodeValue(enc); err != nil { return nil, err } if err := enc.EncodeDumpFooter(); err != nil { return nil, errors.Trace(err) } return b.Bytes(), nil }