示例#1
0
文件: conn.go 项目: fengshao0907/rpdb
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
	}
}
示例#2
0
文件: encoder.go 项目: hushi55/Grep
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
}
示例#3
0
文件: row.go 项目: fengshao0907/rpdb
func loadRpdbRow(r rpdbReader, db uint32, key []byte) (rpdbRow, error) {
	metaKey := EncodeMetaKey(db, key)
	p, err := r.getRowValue(metaKey)
	if err != nil || p == nil {
		return nil, err
	}
	if len(p) == 0 {
		return nil, errors.Trace(ErrObjectCode)
	}
	var o rpdbRow
	var code = ObjectCode(p[0])
	switch code {
	default:
		return nil, errors.Trace(ErrObjectCode)
	case StringCode:
		o = new(stringRow)
	case HashCode:
		o = new(hashRow)
	case ListCode:
		o = new(listRow)
	case ZSetCode:
		o = new(zsetRow)
	case SetCode:
		o = new(setRow)
	}
	o.lazyInit(&rpdbRowHelper{
		code:          code,
		metaKey:       metaKey,
		dataKeyPrefix: EncodeDataKeyPrefix(db, key),
	})
	return o, o.ParseMetaValue(p)
}
示例#4
0
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
}
示例#5
0
文件: encoder.go 项目: hushi55/Grep
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
}
示例#6
0
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
	}
}
示例#7
0
func (p *fileBuffer) writeSome(b []byte) (int, error) {
	if p.f == nil {
		return 0, errors.Trace(ErrClosedBacklog)
	}
	maxlen, offset := woffset(len(b), p.size, 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)
}
示例#8
0
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
}
示例#9
0
func (db *RocksDB) Clear() error {
	if db.rkdb != nil {
		db.rkdb.Close()
		db.rkdb = nil
		db.opts.SetCreateIfMissing(true)
		db.opts.SetErrorIfExists(true)
		if err := gorocks.DestroyDatabase(db.path, db.opts); err != nil {
			return errors.Trace(err)
		} else if db.rkdb, err = gorocks.Open(db.path, db.opts); err != nil {
			return errors.Trace(err)
		}
	}
	return nil
}
示例#10
0
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)
}
示例#11
0
文件: main.go 项目: fengshao0907/rpdb
func Serve(config *Config, bl *rpdb.Rpdb) error {
	h := &Handler{
		config: config,
		master: make(chan *conn, 0),
		signal: make(chan int, 0),
	}
	defer func() {
		close(h.signal)
	}()

	l, err := net.Listen("tcp", config.Listen)
	if err != nil {
		return errors.Trace(err)
	}
	defer l.Close()

	if h.htable, err = redis.NewHandlerTable(h); err != nil {
		return err
	} else {
		go h.daemonSyncMaster()
	}

	log.Infof("open listen address '%s' and start service", l.Addr())

	for {
		if nc, err := l.Accept(); err != nil {
			return errors.Trace(err)
		} else {
			h.counters.clientsAccepted.Add(1)
			go func() {
				h.counters.clients.Add(1)
				defer h.counters.clients.Sub(1)
				c := newConn(nc, bl, h.config.ConnTimeout)
				defer c.Close()
				log.Infof("new connection: %s", c.summ)
				if err := c.serve(h); err != nil {
					if errors.Equal(err, io.EOF) {
						log.Infof("connection lost: %s [io.EOF]", c.summ)
					} else {
						log.InfoErrorf(err, "connection lost: %s", c.summ)
					}
				} else {
					log.Infof("connection exit: %s", c.summ)
				}
			}()
		}
	}
}
示例#12
0
文件: row.go 项目: fengshao0907/rpdb
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
}
示例#13
0
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
	}
}
示例#14
0
文件: decoder.go 项目: hushi55/Grep
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
}
示例#15
0
func ParseFloat(i interface{}) (float64, error) {
	var s string
	switch x := Num64(i).(type) {
	case int64:
		return float64(x), nil
	case uint64:
		return float64(x), nil
	case float64:
		switch {
		case math.IsNaN(x):
			return 0, errors.New("float is NaN")
		case math.IsInf(x, 0):
			return 0, errors.New("float is Inf")
		}
		return float64(x), nil
	case string:
		s = x
	case []byte:
		s = string(x)
	default:
		s = fmt.Sprint(x)
	}
	f, err := strconv.ParseFloat(s, 64)
	return f, errors.Trace(err)
}
示例#16
0
func ParseUint(i interface{}) (uint64, error) {
	var s string
	switch x := Num64(i).(type) {
	case int64:
		if x < 0 {
			return 0, errors.New("integer overflow")
		}
		return uint64(x), nil
	case uint64:
		return uint64(x), nil
	case float64:
		switch {
		case math.IsNaN(x):
			return 0, errors.New("float is NaN")
		case math.IsInf(x, 0):
			return 0, errors.New("float is Inf")
		case math.Abs(x-float64(uint64(x))) > 1e-9:
			return 0, errors.New("float to uint64")
		}
		return uint64(x), nil
	case string:
		s = x
	case []byte:
		s = string(x)
	default:
		s = fmt.Sprint(x)
	}
	u, err := strconv.ParseUint(s, 10, 64)
	return u, errors.Trace(err)
}
示例#17
0
文件: sync.go 项目: fengshao0907/rpdb
// SLAVEOF host port
func (h *Handler) SlaveOf(arg0 interface{}, args [][]byte) (redis.Resp, error) {
	if len(args) != 2 {
		return toRespErrorf("len(args) = %d, expect = 2", len(args))
	}

	s, err := session(arg0, args)
	if err != nil {
		return toRespError(err)
	}

	addr := fmt.Sprintf("%s:%s", string(args[0]), string(args[1]))
	log.Infof("set slave of %s", addr)

	var c *conn
	if strings.ToLower(addr) != "no:one" {
		if nc, err := net.DialTimeout("tcp", addr, time.Second); err != nil {
			return toRespError(errors.Trace(err))
		} else {
			c = newConn(nc, s.Rpdb(), 0)
			if err := c.ping(); err != nil {
				c.Close()
				return toRespError(err)
			}
		}
	}
	select {
	case <-h.signal:
		if c != nil {
			c.Close()
		}
		return toRespErrorf("sync master has been closed")
	case h.master <- c:
		return redis.NewString("OK"), nil
	}
}
示例#18
0
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)
	}
}
示例#19
0
文件: keys.go 项目: fengshao0907/rpdb
func (b *Rpdb) restore(bt *store.Batch, db uint32, key []byte, expireat uint64, obj interface{}) error {
	_, err := b.deleteIfExists(bt, db, key)
	if err != nil {
		return err
	}

	if !IsExpired(expireat) {
		var o rpdbRow
		switch obj.(type) {
		default:
			return errors.Trace(ErrObjectValue)
		case rdb.String:
			o = newStringRow(db, key)
		case rdb.Hash:
			o = newHashRow(db, key)
		case rdb.List:
			o = newListRow(db, key)
		case rdb.ZSet:
			o = newZSetRow(db, key)
		case rdb.Set:
			o = newSetRow(db, key)
		}
		return o.storeObject(b, bt, expireat, obj)
	}

	log.Debugf("restore an expired object, db = %d, key = %v, expireat = %d", db, key, expireat)
	return nil
}
示例#20
0
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)
}
示例#21
0
func (d *decoder) decodeType() (respType, error) {
	if b, err := d.r.ReadByte(); err != nil {
		return 0, errors.Trace(err)
	} else {
		return respType(b), nil
	}
}
示例#22
0
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")
	}
}
示例#23
0
func (db *LevelDB) init(path string, conf *Config, create, repair bool) error {
	if conf == nil {
		conf = NewDefaultConfig()
	}
	opts := levigo.NewOptions()
	if create {
		opts.SetCreateIfMissing(true)
		opts.SetErrorIfExists(true)
	} else {
		opts.SetCreateIfMissing(false)
		opts.SetErrorIfExists(false)
	}

	opts.SetCompression(levigo.SnappyCompression)
	opts.SetBlockSize(conf.BlockSize)
	opts.SetWriteBufferSize(conf.WriteBufferSize)
	opts.SetMaxOpenFiles(conf.MaxOpenFiles)

	cache := levigo.NewLRUCache(conf.CacheSize)
	opts.SetCache(cache)

	bloom := levigo.NewBloomFilter(conf.BloomFilterSize)
	opts.SetFilterPolicy(bloom)

	db.path = path
	db.opts = opts
	db.ropt = levigo.NewReadOptions()
	db.wopt = levigo.NewWriteOptions()
	db.cache = cache
	db.bloom = bloom

	if create {
		if err := os.MkdirAll(db.path, 0700); err != nil {
			return errors.Trace(err)
		}
	} else if repair {
		if err := levigo.RepairDatabase(db.path, db.opts); err != nil {
			return errors.Trace(err)
		}
	}

	var err error
	if db.lvdb, err = levigo.Open(db.path, db.opts); err != nil {
		return errors.Trace(err)
	}
	return nil
}
示例#24
0
文件: rpdb.go 项目: fengshao0907/rpdb
func (b *Rpdb) acquire() error {
	b.mu.Lock()
	if b.db != nil {
		return nil
	}
	b.mu.Unlock()
	return errors.Trace(ErrClosed)
}
示例#25
0
func (p *fileBuffer) close() error {
	if f := p.f; f != nil {
		p.f = nil
		defer f.Close()
		return errors.Trace(f.Truncate(0))
	}
	return nil
}
示例#26
0
func (s *RpdbSnapshot) acquire() error {
	s.mu.Lock()
	if s.sp != nil {
		return nil
	}
	s.mu.Unlock()
	return errors.Trace(ErrSnapClosed)
}
示例#27
0
func (it *Iterator) Error() error {
	if it.err == nil {
		if err := it.iter.GetError(); err != nil {
			it.err = errors.Trace(err)
		}
	}
	return it.err
}
示例#28
0
func (w *BufWriter) WriteVarbytes(p []byte) error {
	if n := uint64(len(p)); n > maxVarbytesLen {
		return errors.Trace(ErrVarbytesLen)
	} else if err := w.WriteUvarint(n); err != nil {
		return err
	}
	_, err := ioutils.WriteFull(w.w, p)
	return err
}
示例#29
0
func (c *conn) encodeResp(resp redis.Resp, timeout time.Duration) error {
	if err := c.sock.SetWriteDeadline(time.Now().Add(timeout)); err != nil {
		return err
	}
	if err := redis.Encode(c.w, resp); err != nil {
		return err
	}
	return errors.Trace(c.w.Flush())
}
示例#30
0
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
}