Exemple #1
0
func lrangeCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	var start int64
	var stop int64
	var err error

	start, err = ledis.StrInt64(args[1], nil)
	if err != nil {
		return err
	}

	stop, err = ledis.StrInt64(args[2], nil)
	if err != nil {
		return err
	}

	if v, err := c.db.LRange(args[0], int32(start), int32(stop)); err != nil {
		return err
	} else {
		c.writeArray(v)
	}

	return nil
}
Exemple #2
0
func lrangeCommand(req *requestContext) error {
	args := req.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	var start int64
	var stop int64
	var err error

	start, err = ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrValue
	}

	stop, err = ledis.StrInt64(args[2], nil)
	if err != nil {
		return ErrValue
	}

	if v, err := req.db.LRange(args[0], int32(start), int32(stop)); err != nil {
		return err
	} else {
		req.resp.writeSliceArray(v)
	}

	return nil
}
Exemple #3
0
func lTrimCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	var start int64
	var stop int64
	var err error

	start, err = ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrValue
	}
	stop, err = ledis.StrInt64(args[2], nil)
	if err != nil {
		return ErrValue
	}

	if err := c.db.LTrim(args[0], start, stop); err != nil {
		return err
	} else {
		c.resp.writeStatus(OK)
	}

	return nil
}
Exemple #4
0
func syncCommand(req *requestContext) error {
	args := req.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	var logIndex int64
	var logPos int64
	var err error
	logIndex, err = ledis.StrInt64(args[0], nil)
	if err != nil {
		return ErrCmdParams
	}

	logPos, err = ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrCmdParams
	}

	req.syncBuf.Reset()

	//reserve space to write master info
	if _, err := req.syncBuf.Write(reserveInfoSpace); err != nil {
		return err
	}

	m := &ledis.MasterInfo{logIndex, logPos}

	if _, err := req.app.ldb.ReadEventsTo(m, &req.syncBuf); err != nil {
		return err
	} else {
		buf := req.syncBuf.Bytes()

		binary.BigEndian.PutUint64(buf[0:], uint64(m.LogFileIndex))
		binary.BigEndian.PutUint64(buf[8:], uint64(m.LogPos))

		if len(req.compressBuf) < snappy.MaxEncodedLen(len(buf)) {
			req.compressBuf = make([]byte, snappy.MaxEncodedLen(len(buf)))
		}

		if buf, err = snappy.Encode(req.compressBuf, buf); err != nil {
			return err
		}

		req.resp.writeBulk(buf)
	}

	return nil
}
Exemple #5
0
func syncCommand(c *client) error {
	args := c.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	var logIndex int64
	var logPos int64
	var err error
	logIndex, err = ledis.StrInt64(args[0], nil)
	if err != nil {
		return ErrCmdParams
	}

	logPos, err = ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrCmdParams
	}

	c.syncBuf.Reset()

	//reserve space to write binlog anchor
	if _, err := c.syncBuf.Write(reserveInfoSpace); err != nil {
		return err
	}

	m := &ledis.BinLogAnchor{logIndex, logPos}

	if _, err := c.app.ldb.ReadEventsToTimeout(m, &c.syncBuf, 5); err != nil {
		return err
	} else {
		buf := c.syncBuf.Bytes()

		binary.BigEndian.PutUint64(buf[0:], uint64(m.LogFileIndex))
		binary.BigEndian.PutUint64(buf[8:], uint64(m.LogPos))

		if len(c.compressBuf) < snappy.MaxEncodedLen(len(buf)) {
			c.compressBuf = make([]byte, snappy.MaxEncodedLen(len(buf)))
		}

		if buf, err = snappy.Encode(c.compressBuf, buf); err != nil {
			return err
		}

		c.resp.writeBulk(buf)
	}

	return nil
}
Exemple #6
0
func zaddCommand(c *client) error {
	args := c.args
	if len(args) < 3 {
		return ErrCmdParams
	}

	key := args[0]
	if len(args[1:])%2 != 0 {
		return ErrCmdParams
	}

	args = args[1:]

	params := make([]ledis.ScorePair, len(args)/2)
	for i := 0; i < len(params); i++ {
		score, err := ledis.StrInt64(args[2*i], nil)
		if err != nil {
			return err
		}

		params[i].Score = score
		params[i].Member = args[2*i+1]
	}

	if n, err := c.db.ZAdd(key, params...); err != nil {
		return err
	} else {
		c.writeInteger(n)
	}

	return nil
}
Exemple #7
0
func zexpireAtCommand(req *requestContext) error {
	args := req.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	when, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrValue
	}

	if v, err := req.db.ZExpireAt(args[0], when); err != nil {
		return err
	} else {
		req.resp.writeInteger(v)
	}
	return nil
}
Exemple #8
0
func lindexCommand(req *requestContext) error {
	args := req.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	index, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrValue
	}

	if v, err := req.db.LIndex(args[0], int32(index)); err != nil {
		return err
	} else {
		req.resp.writeBulk(v)
	}

	return nil
}
Exemple #9
0
func decrbyCommand(req *requestContext) error {
	args := req.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	delta, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrValue
	}

	if n, err := req.db.DecrBy(req.args[0], delta); err != nil {
		return err
	} else {
		req.resp.writeInteger(n)
	}

	return nil
}
Exemple #10
0
func setexCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	sec, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrValue
	}

	if err := c.db.SetEX(args[0], sec, args[2]); err != nil {
		return err
	} else {
		c.resp.writeStatus(OK)
	}

	return nil
}
Exemple #11
0
func decrbyCommand(c *client) error {
	args := c.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	delta, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return err
	}

	if n, err := c.db.DecrBy(c.args[0], delta); err != nil {
		return err
	} else {
		c.writeInteger(n)
	}

	return nil
}
Exemple #12
0
func zexpireAtCommand(c *client) error {
	args := c.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	when, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return err
	}

	if v, err := c.db.ZExpireAt(args[0], when); err != nil {
		return err
	} else {
		c.writeInteger(v)
	}

	return nil
}
Exemple #13
0
func hexpireCommand(c *client) error {
	args := c.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	duration, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrValue
	}

	if v, err := c.db.HExpire(args[0], duration); err != nil {
		return err
	} else {
		c.resp.writeInteger(v)
	}

	return nil
}
Exemple #14
0
func hincrbyCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	delta, err := ledis.StrInt64(args[2], nil)
	if err != nil {
		return ErrValue
	}

	var n int64
	if n, err = c.db.HIncrBy(args[0], args[1], delta); err != nil {
		return err
	} else {
		c.resp.writeInteger(n)
	}
	return nil
}
Exemple #15
0
func lindexCommand(c *client) error {
	args := c.args
	if len(args) != 2 {
		return ErrCmdParams
	}

	index, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return err
	}

	if v, err := c.db.LIndex(args[0], int32(index)); err != nil {
		return err
	} else {
		c.writeBulk(v)
	}

	return nil
}
Exemple #16
0
func zincrbyCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	key := args[0]

	delta, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return err
	}

	if v, err := c.db.ZIncrBy(key, delta, args[2]); err != nil {
		return err
	} else {
		c.writeBulk(ledis.StrPutInt64(v))
	}

	return nil
}
Exemple #17
0
// unlike redis, restore will try to delete old key first
func restoreCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	key := args[0]
	ttl, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return err
	}
	data := args[2]

	if err = c.db.Restore(key, ttl, data); err != nil {
		return err
	} else {
		c.resp.writeStatus(OK)
	}

	return nil
}
Exemple #18
0
func zincrbyCommand(c *client) error {
	args := c.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	key := args[0]

	delta, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrValue
	}

	v, err := c.db.ZIncrBy(key, delta, args[2])

	if err == nil {
		c.resp.writeBulk(num.FormatInt64ToSlice(v))
	}

	return err
}
Exemple #19
0
func zincrbyCommand(req *requestContext) error {
	args := req.args
	if len(args) != 3 {
		return ErrCmdParams
	}

	key := args[0]

	delta, err := ledis.StrInt64(args[1], nil)
	if err != nil {
		return ErrValue
	}

	if v, err := req.db.ZIncrBy(key, delta, args[2]); err != nil {
		return err
	} else {
		req.resp.writeBulk(ledis.StrPutInt64(v))
	}

	return nil
}
Exemple #20
0
// maybe only used in xcodis for redis data port
func xrestoreCommand(c *client) error {
	args := c.args
	if len(args) != 4 {
		return ErrCmdParams
	}

	//	tp := strings.ToUpper(string(args[2]))
	key := args[1]
	ttl, err := ledis.StrInt64(args[2], nil)
	if err != nil {
		return err
	}
	data := args[3]

	if err = c.db.Restore(key, ttl, data); err != nil {
		return err
	} else {
		c.resp.writeStatus(OK)
	}

	return nil
}
Exemple #21
0
//XMIGRATE host port type key destination-db timeout
//will block any other write operations
//maybe only for xcodis
func xmigrateCommand(c *client) error {
	args := c.args

	if len(args) != 6 {
		return ErrCmdParams
	}

	addr := fmt.Sprintf("%s:%s", string(args[0]), string(args[1]))
	if addr == c.app.cfg.Addr {
		//same server, can not migrate
		return fmt.Errorf("migrate in same server is not allowed")
	}

	tp := strings.ToUpper(string(args[2]))
	key := args[3]
	db, err := parseMigrateDB(c, args[4])
	if err != nil {
		return err
	}

	timeout, err := ledis.StrInt64(args[5], nil)
	if err != nil {
		return err
	} else if timeout < 0 {
		return fmt.Errorf("invalid timeout %d", timeout)
	}

	conn, err := getMigrateDBConn(c, addr, db)
	if err != nil {
		return err
	}
	defer conn.Close()

	// if key is in migrating, we will wait 500ms and retry again
	for i := 0; i < 10; i++ {
		if tp == "ALL" {
			// if tp is ALL, we will migrate the key in all types
			// this feature is useful for xcodis RESTORE or other commands that we don't know the data type exactly
			err = migrateAllTypeKeys(c, conn, key, timeout)
		} else {
			err = migrateKey(c, conn, tp, key, timeout)
		}

		if err != errKeyInMigrating {
			break
		} else {
			log.Infof("%s key %s is in migrating, wait 500ms and retry", tp, key)
			time.Sleep(500 * time.Millisecond)
		}
	}

	if err != nil {
		if err == errNoKey {
			c.resp.writeStatus(NOKEY)
			return nil
		} else {
			return err
		}
	}

	c.resp.writeStatus(OK)
	return nil
}
Exemple #22
0
func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err error) {
	if strings.ToLower(ledis.String(minBuf)) == "-inf" {
		min = math.MinInt64
	} else {
		var lopen bool = false
		if minBuf[0] == '(' {
			lopen = true
			minBuf = minBuf[1:]
		}

		if len(minBuf) == 0 {
			err = ErrCmdParams
			return
		}

		min, err = ledis.StrInt64(minBuf, nil)
		if err != nil {
			return
		}

		if min <= ledis.MinScore || min >= ledis.MaxScore {
			err = errScoreOverflow
			return
		}

		if lopen {
			min++
		}
	}

	if strings.ToLower(ledis.String(maxBuf)) == "+inf" {
		max = math.MaxInt64
	} else {
		var ropen = false
		if maxBuf[0] == '(' {
			ropen = true
			maxBuf = maxBuf[1:]
		}

		if len(maxBuf) == 0 {
			err = ErrCmdParams
			return
		}

		max, err = ledis.StrInt64(maxBuf, nil)
		if err != nil {
			return
		}

		if max <= ledis.MinScore || max >= ledis.MaxScore {
			err = errScoreOverflow
			return
		}

		if ropen {
			max--
		}
	}

	return
}
Exemple #23
0
func (s *store) GetInt64(k []byte) (int64, error) {
	return ledis.StrInt64(s.db.Get(k))
}
Exemple #24
0
func zparseZsetoptStore(args [][]byte) (destKey []byte, srcKeys [][]byte, weights []int64, aggregate byte, err error) {
	destKey = args[0]
	nKeys, err := strconv.Atoi(hack.String(args[1]))
	if err != nil {
		err = ErrValue
		return
	}
	args = args[2:]
	if len(args) < nKeys {
		err = ErrSyntax
		return
	}

	srcKeys = args[:nKeys]

	args = args[nKeys:]

	var weightsFlag = false
	var aggregateFlag = false

	for len(args) > 0 {
		if strings.ToLower(hack.String(args[0])) == "weights" {
			if weightsFlag {
				err = ErrSyntax
				return
			}

			args = args[1:]
			if len(args) < nKeys {
				err = ErrSyntax
				return
			}

			weights = make([]int64, nKeys)
			for i, arg := range args[:nKeys] {
				if weights[i], err = ledis.StrInt64(arg, nil); err != nil {
					err = ErrValue
					return
				}
			}
			args = args[nKeys:]

			weightsFlag = true

		} else if strings.ToLower(hack.String(args[0])) == "aggregate" {
			if aggregateFlag {
				err = ErrSyntax
				return
			}
			if len(args) < 2 {
				err = ErrSyntax
				return
			}

			if strings.ToLower(hack.String(args[1])) == "sum" {
				aggregate = ledis.AggregateSum
			} else if strings.ToLower(hack.String(args[1])) == "min" {
				aggregate = ledis.AggregateMin
			} else if strings.ToLower(hack.String(args[1])) == "max" {
				aggregate = ledis.AggregateMax
			} else {
				err = ErrSyntax
				return
			}
			args = args[2:]
			aggregateFlag = true
		} else {
			err = ErrSyntax
			return
		}
	}
	if !aggregateFlag {
		aggregate = ledis.AggregateSum
	}
	return
}
Exemple #25
0
//XMIGRATEDB host port tp count db timeout
//select count tp type keys and migrate
//will block any other write operations
//maybe only for xcodis
func xmigratedbCommand(c *client) error {
	args := c.args
	if len(args) != 6 {
		return ErrCmdParams
	}

	addr := fmt.Sprintf("%s:%s", string(args[0]), string(args[1]))
	if addr == c.app.cfg.Addr {
		//same server, can not migrate
		return fmt.Errorf("migrate in same server is not allowed")
	}

	tp := strings.ToUpper(string(args[2]))

	count, err := ledis.StrInt64(args[3], nil)
	if err != nil {
		return err
	} else if count <= 0 {
		count = 10
	}

	db, err := parseMigrateDB(c, args[4])
	if err != nil {
		return err
	}

	timeout, err := ledis.StrInt64(args[5], nil)
	if err != nil {
		return err
	} else if timeout < 0 {
		return fmt.Errorf("invalid timeout %d", timeout)
	}

	keys, err := xscan(c.db, tp, int(count))
	if err != nil {
		return err
	} else if len(keys) == 0 {
		c.resp.writeInteger(0)
		return nil
	}

	conn, err := getMigrateDBConn(c, addr, db)
	if err != nil {
		return err
	}
	defer conn.Close()

	migrateNum := int64(0)
	for _, key := range keys {
		err = migrateKey(c, conn, tp, key, timeout)
		if err != nil {
			if err == errNoKey || err == errKeyInMigrating {
				continue
			} else {
				return err
			}
		}

		migrateNum++
	}

	c.resp.writeInteger(migrateNum)

	return nil
}