func (c *client) writeError(err error) { c.wb.Write(hack.Slice("-ERR")) if err != nil { c.wb.WriteByte(' ') c.wb.Write(hack.Slice(err.Error())) } c.wb.Write(Delims) }
func (a *App) hash_incrby(key []byte, field []byte, delta int64) (int64, error) { t := a.hashTx t.Lock() defer t.Unlock() ek := encode_hash_key(key, field) var n int64 = 0 v, err := a.db.Get(ek) if err != nil { return 0, err } else if v != nil { if n, err = strconv.ParseInt(hack.String(v), 10, 64); err != nil { return 0, err } } n += delta _, err = a.hash_setItem(key, field, hack.Slice(strconv.FormatInt(n, 10))) if err != nil { return 0, err } err = t.Commit() return n, err }
func (a *App) hash_mset(key []byte, args [][]byte) error { sk := encode_hsize_key(key) t := a.hashTx t.Lock() defer t.Unlock() size, err := a.db.GetInt(sk) if err != nil { return err } for i := 0; i < len(args); i += 2 { ek := encode_hash_key(key, args[i]) if v, _ := a.db.Get(ek); v == nil { size++ } t.Put(ek, args[i+1]) } t.Put(sk, hack.Slice(strconv.FormatInt(size, 10))) //todo add binglog err = t.Commit() return err }
func (a *App) zset_incrby(key []byte, delta int64, member []byte) ([]byte, error) { t := a.zsetTx t.Lock() defer t.Unlock() ek := encode_zset_key(key, member) var score int64 = delta v, err := a.db.Get(ek) if err != nil { return nil, err } else if v != nil { if s, err := Int64(v, err); err != nil { return nil, err } else { sk := encode_zscore_key(key, member, s) t.Delete(sk) score = s + delta if score >= MaxScore || score <= MinScore { return nil, errScoreOverflow } } } else { a.zset_incrSize(key, 1) } t.Put(ek, PutInt64(score)) t.Put(encode_zscore_key(key, member, score), []byte{}) err = t.Commit() return hack.Slice(strconv.FormatInt(score, 10)), err }
func (c *client) writeArray(ay []interface{}) { c.wb.WriteByte('*') if ay == nil { c.wb.Write(NullArray) c.wb.Write(Delims) } else { c.wb.Write(hack.Slice(strconv.Itoa(len(ay)))) c.wb.Write(Delims) for i := 0; i < len(ay); i++ { switch v := ay[i].(type) { case []interface{}: c.writeArray(v) case []byte: c.writeBulk(v) case nil: c.writeBulk(nil) case int64: c.writeInteger(v) default: panic("invalid array type") } } } }
func (a *App) zset_score(key []byte, member []byte) ([]byte, error) { k := encode_zset_key(key, member) score, err := Int64(a.db.Get(k)) if err != nil { return nil, err } return hack.Slice(strconv.FormatInt(score, 10)), nil }
func (c *client) writeBulk(b []byte) { c.wb.WriteByte('$') if b == nil { c.wb.Write(NullBulk) } else { c.wb.Write(hack.Slice(strconv.Itoa(len(b)))) c.wb.Write(Delims) c.wb.Write(b) } c.wb.Write(Delims) }
func (a *App) zset_range(key []byte, min int64, max int64, withScores bool, offset int, limit int, reverse bool) ([]interface{}, error) { nv := 64 if limit > 0 { nv = limit } if withScores { nv = 2 * nv } v := make([]interface{}, 0, nv) var it *leveldb.Iterator //if reverse and offset is 0, limit < 0, we may use forward iterator then reverse //because leveldb iterator prev is slower than next if !reverse || (offset == 0 && limit < 0) { it = a.zset_iterator(key, min, max, offset, limit, false) } else { it = a.zset_iterator(key, min, max, offset, limit, true) } for ; it.Valid(); it.Next() { _, m, s, err := decode_zscore_key(it.Key()) //may be we will check key equal? if err != nil { continue } v = append(v, m) if withScores { v = append(v, hack.Slice(strconv.FormatInt(s, 10))) } } if reverse && (offset == 0 && limit < 0) { v = a.zset_reverse(v, withScores) } return v, nil }
func (a *App) hash_setItem(key []byte, field []byte, value []byte) (int64, error) { t := a.hashTx ek := encode_hash_key(key, field) sk := encode_hsize_key(key) size, err := a.db.GetInt(sk) if err != nil { return 0, err } var n int64 = 1 if v, _ := a.db.Get(ek); v != nil { n = 0 } else { size++ t.Put(sk, hack.Slice(strconv.FormatInt(size, 10))) } t.Put(ek, value) return n, nil }
func (a *App) hash_del(key []byte, args [][]byte) (int64, error) { sk := encode_hsize_key(key) t := a.hashTx t.Lock() defer t.Unlock() size, err := a.db.GetInt(sk) if err != nil { return 0, err } var num int64 = 0 for i := 0; i < len(args); i++ { ek := encode_hash_key(key, args[i]) if v, err := a.db.Get(ek); err != nil { return 0, err } else if v == nil { continue } else { num++ size-- t.Delete(ek) } } if size <= 0 { t.Delete(sk) } else { t.Put(sk, hack.Slice(strconv.FormatInt(size, 10))) } err = t.Commit() return num, err }
func (a *App) kv_incr(key []byte, delta int64) (int64, error) { key = encode_kv_key(key) var err error t := a.kvTx t.Lock() defer t.Unlock() var n int64 n, err = a.db.GetInt(key) if err != nil { return 0, err } n += delta t.Put(key, hack.Slice(strconv.FormatInt(n, 10))) //todo binlog err = t.Commit() return n, err }
func (c *client) writeInteger(n int64) { c.wb.WriteByte(':') c.wb.Write(hack.Slice(strconv.FormatInt(n, 10))) c.wb.Write(Delims) }
func (c *client) writeStatus(status string) { c.wb.WriteByte('+') c.wb.Write(hack.Slice(status)) c.wb.Write(Delims) }