func (l *LevelZSet) Add(scoreMembers ...[]byte) (n int) { l.mu.Lock() defer l.mu.Unlock() batch := gorocks.NewWriteBatch() defer batch.Close() count := len(scoreMembers) for i := 0; i < count; i += 2 { score := scoreMembers[i] member, memberkey := scoreMembers[i+1], l.memberKey(scoreMembers[i+1]) // remove old score oldscore, _ := l.redis.RawGet(memberkey) if oldscore != nil { batch.Delete(l.scoreKey(member, oldscore)) } else { l.totalCount++ // The number of elements added to the sorted sets, not including elements already existing for which the score was updated. n++ } // set member batch.Put(memberkey, score) // new score batch.Put(l.scoreKey(member, score), nil) } batch.Put(l.zsetKey(), l.zsetValue()) err := l.redis.WriteBatch(batch) if err != nil { panic(err) } return }
// 保留左边 func (l *LevelList) TrimLeft(count uint) (n int) { l.mu.Lock() defer l.mu.Unlock() oldlen := l.len() if oldlen == 0 || oldlen <= int64(count) { return } oldstart, oldend := l.start, l.end batch := gorocks.NewWriteBatch() defer batch.Close() for i := int64(count); i < oldlen; i++ { idx := oldstart + i // fmt.Println("LTRIM", l.entryKey, "i=", i, ", idx=", idx) batch.Delete(l.idxKey(idx)) l.end-- } shouldReset := l.len() == 0 if shouldReset { l.start = 0 l.end = -1 batch.Delete(l.infoKey()) } else { batch.Put(l.infoKey(), l.infoValue()) } err := l.redis.WriteBatch(batch) if err != nil { // 回退 l.start, l.end = oldstart, oldend } return }
func (l *LevelZSet) RemoveByScore(min, max int64) (n int) { l.mu.Lock() defer l.mu.Unlock() min2 := l.scoreKeyPrefixWith(min) max2 := joinBytes(l.scoreKeyPrefixWith(max), []byte{MAXBYTE}) batch := gorocks.NewWriteBatch() defer batch.Close() l.redis.RangeEnumerate(min2, max2, IterForward, func(i int, key, value []byte, quit *bool) { score, member := l.splitScoreKey(key) batch.Delete(l.memberKey(member)) batch.Delete(l.scoreKey(member, score)) n++ }) l.totalCount -= n if l.totalCount == 0 { batch.Delete(l.zsetKey()) } else { batch.Put(l.zsetKey(), l.zsetValue()) } err := l.redis.WriteBatch(batch) if err != nil { panic(err) } return }
func (l *LevelZSet) RemoveByIndex(start, stop int) (n int) { l.mu.Lock() defer l.mu.Unlock() batch := gorocks.NewWriteBatch() defer batch.Close() l.redis.PrefixEnumerate(l.scoreKeyPrefix(), IterForward, func(i int, key, value []byte, quit *bool) { if i < start { return } else if i >= start && (stop == -1 || i <= stop) { score, member := l.splitScoreKey(key) batch.Delete(l.memberKey(member)) batch.Delete(l.scoreKey(member, score)) n++ } else { *quit = true } }) l.totalCount -= n if l.totalCount == 0 { batch.Delete(l.zsetKey()) } else { batch.Put(l.zsetKey(), l.zsetValue()) } err := l.redis.WriteBatch(batch) if err != nil { panic(err) } return }
func (l *LevelZSet) Remove(members ...[]byte) (n int) { l.mu.Lock() defer l.mu.Unlock() batch := gorocks.NewWriteBatch() defer batch.Close() for _, member := range members { score, _ := l.redis.RawGet(l.memberKey(member)) if score == nil { continue } batch.Delete(l.memberKey(member)) batch.Delete(l.scoreKey(member, score)) n++ } l.totalCount -= n if l.totalCount == 0 { batch.Delete(l.zsetKey()) } else { batch.Put(l.zsetKey(), l.zsetValue()) } err := l.redis.WriteBatch(batch) if err != nil { panic(err) } return }
func (l *LevelZSet) IncrBy(member []byte, incr int64) (newscore []byte) { l.mu.Lock() defer l.mu.Unlock() score := l.score(member) batch := gorocks.NewWriteBatch() defer batch.Close() oldcount := l.totalCount if score == nil { newscore = Int64ToBytes(incr) l.totalCount++ } else { batch.Delete(l.scoreKey(member, score)) scoreInt := BytesToInt64(score) newscore = Int64ToBytes(scoreInt + incr) } batch.Put(l.memberKey(member), newscore) batch.Put(l.scoreKey(member, newscore), nil) if l.totalCount != oldcount { batch.Put(l.zsetKey(), l.zsetValue()) } err := l.redis.WriteBatch(batch) if err != nil { l.totalCount = oldcount panic(err) // need refect } return }
func (l *LevelHash) Drop() (ok bool) { l.mu.Lock() defer l.mu.Unlock() batch := gorocks.NewWriteBatch() defer batch.Close() l.redis.PrefixEnumerate(l.fieldPrefix(), IterForward, func(i int, key, value []byte, quit *bool) { batch.Delete(key) }) batch.Delete(l.infoKey()) l.redis.WriteBatch(batch) ok = true return }
func (l *LevelHash) Set(fieldVals ...[]byte) (n int) { l.mu.Lock() defer l.mu.Unlock() batch := gorocks.NewWriteBatch() defer batch.Close() n = 0 for i := 0; i < len(fieldVals); i += 2 { fieldkey := l.fieldKey(fieldVals[i]) batch.Put(fieldkey, fieldVals[i+1]) n++ } if n > 0 { batch.Put(l.infoKey(), l.infoValue()) l.redis.WriteBatch(batch) } return }
func (l *LevelList) LPush(values ...[]byte) (err error) { l.mu.Lock() defer l.mu.Unlock() // 左游标 oldstart := l.start batch := gorocks.NewWriteBatch() defer batch.Close() for _, value := range values { l.start-- batch.Put(l.idxKey(l.start), value) } batch.Put(l.infoKey(), l.infoValue()) err = l.redis.WriteBatch(batch) if err != nil { // 回退 l.start = oldstart } return }
func (l *LevelList) RPush(values ...[]byte) (err error) { l.mu.Lock() defer l.mu.Unlock() // 右游标 oldend := l.end batch := gorocks.NewWriteBatch() defer batch.Close() for _, value := range values { l.end++ batch.Put(l.idxKey(l.end), value) } batch.Put(l.infoKey(), l.infoValue()) err = l.redis.WriteBatch(batch) if err != nil { // 回退 l.end = oldend } return }
func (l *LevelZSet) Drop() (ok bool) { l.mu.Lock() defer l.mu.Unlock() if l.totalCount == 0 { return true } batch := gorocks.NewWriteBatch() defer batch.Close() prefix := joinStringBytes(ZSET_PREFIX, SEP_LEFT, l.key, SEP_RIGHT) l.redis.PrefixEnumerate(prefix, IterForward, func(i int, key, value []byte, quit *bool) { batch.Delete(key) }) batch.Delete(l.zsetKey()) err := l.redis.WriteBatch(batch) if err != nil { panic(err) } l.totalCount = 0 ok = true return }
func (l *LevelList) RPop() (e *Element, err error) { l.mu.Lock() defer l.mu.Unlock() if l.len() == 0 { return nil, nil } // backup oldstart, oldend := l.start, l.end // get idx := l.end e = &Element{} e.Value, err = l.redis.RawGet(l.idxKey(idx)) if err != nil || e.Value == nil { return } // 只剩下一个元素时,删除infoKey(0) shouldReset := l.len() == 1 // 删除数据, 更新左游标 batch := gorocks.NewWriteBatch() defer batch.Close() batch.Delete(l.idxKey(idx)) if shouldReset { l.start = 0 l.end = -1 batch.Delete(l.infoKey()) } else { l.end-- batch.Put(l.infoKey(), l.infoValue()) } err = l.redis.WriteBatch(batch) if err != nil { // 回退 l.start, l.end = oldstart, oldend } return }