コード例 #1
0
ファイル: encoder.go プロジェクト: left2right/redis-port
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
}
コード例 #2
0
ファイル: encoder.go プロジェクト: left2right/redis-port
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
}
コード例 #3
0
ファイル: decoder.go プロジェクト: left2right/redis-port
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
	}
}
コード例 #4
0
ファイル: encoder.go プロジェクト: left2right/redis-port
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
}
コード例 #5
0
ファイル: file.go プロジェクト: left2right/redis-port
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)
}
コード例 #6
0
ファイル: decoder.go プロジェクト: left2right/redis-port
func (d *decoder) decodeType() (respType, error) {
	if b, err := d.r.ReadByte(); err != nil {
		return 0, errors.Trace(err)
	} else {
		return respType(b), nil
	}
}
コード例 #7
0
ファイル: decoder.go プロジェクト: left2right/redis-port
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
}
コード例 #8
0
ファイル: utils.go プロジェクト: left2right/redis-port
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")
	}
}
コード例 #9
0
ファイル: utils.go プロジェクト: left2right/redis-port
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)
}
コード例 #10
0
ファイル: encoder.go プロジェクト: left2right/redis-port
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
	}
}
コード例 #11
0
ファイル: file.go プロジェクト: left2right/redis-port
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
}
コード例 #12
0
ファイル: bytesize.go プロジェクト: left2right/redis-port
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
}
コード例 #13
0
ファイル: encoder.go プロジェクト: left2right/redis-port
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())
}
コード例 #14
0
ファイル: decoder.go プロジェクト: left2right/redis-port
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
}
コード例 #15
0
ファイル: file.go プロジェクト: left2right/redis-port
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)
}
コード例 #16
0
ファイル: decoder.go プロジェクト: left2right/redis-port
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
	}
}
コード例 #17
0
ファイル: decoder.go プロジェクト: left2right/redis-port
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
	}
}
コード例 #18
0
ファイル: buff.go プロジェクト: left2right/redis-port
func (p *memBuffer) writeSome(b []byte) (int, error) {
	if p.b == 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 := copy(p.b[offset:offset+maxlen], b)
	p.wpos += uint64(n)
	return n, nil
}
コード例 #19
0
ファイル: pipe.go プロジェクト: left2right/redis-port
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()
}
コード例 #20
0
ファイル: loader.go プロジェクト: left2right/redis-port
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
}
コード例 #21
0
ファイル: buff.go プロジェクト: left2right/redis-port
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
}
コード例 #22
0
ファイル: encoder.go プロジェクト: left2right/redis-port
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
}
コード例 #23
0
ファイル: decoder.go プロジェクト: left2right/redis-port
func (d *decoder) decodeArray(depth int) ([]Resp, error) {
	n, err := d.decodeInt()
	if err != nil {
		return nil, err
	}
	if n < -1 {
		return nil, errors.Trace(ErrBadRespArrayLen)
	} else if n == -1 {
		return nil, nil
	}
	a := make([]Resp, n)
	for i := 0; i < len(a); i++ {
		if a[i], err = d.decodeResp(depth + 1); err != nil {
			return nil, err
		}
	}
	return a, nil
}
コード例 #24
0
ファイル: pipe.go プロジェクト: left2right/redis-port
func (p *pipe) writeSome(b []byte) (int, error) {
	p.mu.Lock()
	defer p.mu.Unlock()
	if p.werr != nil {
		return 0, errors.Trace(io.ErrClosedPipe)
	}
	if p.rerr != nil {
		return 0, p.rerr
	}
	if len(b) == 0 {
		return 0, nil
	}
	n, err := p.store.writeSome(b)
	if err != nil || n != 0 {
		p.rwait.Signal()
		return n, err
	}
	p.wwait.Wait()
	return 0, nil
}
コード例 #25
0
ファイル: reader.go プロジェクト: left2right/redis-port
func (r *rdbReader) readFloat() (float64, error) {
	u, err := r.readUint8()
	if err != nil {
		return 0, err
	}
	switch u {
	case 253:
		return math.NaN(), nil
	case 254:
		return math.Inf(0), nil
	case 255:
		return math.Inf(-1), nil
	default:
		if b, err := r.readBytes(int(u)); err != nil {
			return 0, err
		} else {
			v, err := strconv.ParseFloat(string(b), 64)
			return v, errors.Trace(err)
		}
	}
}
コード例 #26
0
ファイル: decoder.go プロジェクト: left2right/redis-port
func (d *decoder) decodeResp(depth int) (Resp, error) {
	t, err := d.decodeType()
	if err != nil {
		return nil, err
	}
	switch t {
	case typeString:
		resp := &String{}
		resp.Value, err = d.decodeText()
		return resp, err
	case typeError:
		resp := &Error{}
		resp.Value, err = d.decodeText()
		return resp, err
	case typeInt:
		resp := &Int{}
		resp.Value, err = d.decodeInt()
		return resp, err
	case typeBulkBytes:
		resp := &BulkBytes{}
		resp.Value, err = d.decodeBulkBytes()
		return resp, err
	case typeArray:
		resp := &Array{}
		resp.Value, err = d.decodeArray(depth)
		return resp, err
	default:
		if depth != 0 {
			return nil, errors.Errorf("bad resp type %s", t)
		}
		if err := d.r.UnreadByte(); err != nil {
			return nil, errors.Trace(err)
		}
		return d.decodeSingleLineBulkBytesArray()
	}
}
コード例 #27
0
ファイル: reader.go プロジェクト: left2right/redis-port
func (r *rdbReader) readByte() (byte, error) {
	b := r.buf[:1]
	_, err := io.ReadFull(r, b)
	return b[0], errors.Trace(err)
}
コード例 #28
0
ファイル: reader.go プロジェクト: left2right/redis-port
func (r *rdbReader) Read(p []byte) (int, error) {
	n, err := r.raw.Read(p)
	r.nread += int64(n)
	return n, errors.Trace(err)
}
コード例 #29
0
ファイル: reader.go プロジェクト: left2right/redis-port
func (r *rdbReader) readFull(p []byte) error {
	_, err := io.ReadFull(r, p)
	return errors.Trace(err)
}
コード例 #30
0
ファイル: log.go プロジェクト: left2right/redis-port
func OpenFile(path string) (*os.File, error) {
	f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666)
	return f, errors.Trace(err)
}