github.com/flower-corp/rosedb@v1.1.2-0.20230117132829-21dc4f7b319a/zset.go (about) 1 package rosedb 2 3 import ( 4 "github.com/flower-corp/rosedb/ds/art" 5 "github.com/flower-corp/rosedb/logfile" 6 "github.com/flower-corp/rosedb/logger" 7 "github.com/flower-corp/rosedb/util" 8 ) 9 10 // ZAdd adds the specified member with the specified score to the sorted set stored at key. 11 func (db *RoseDB) ZAdd(key []byte, score float64, member []byte) error { 12 db.zsetIndex.mu.Lock() 13 defer db.zsetIndex.mu.Unlock() 14 15 if err := db.zsetIndex.murhash.Write(member); err != nil { 16 return err 17 } 18 sum := db.zsetIndex.murhash.EncodeSum128() 19 db.zsetIndex.murhash.Reset() 20 if db.zsetIndex.trees[string(key)] == nil { 21 db.zsetIndex.trees[string(key)] = art.NewART() 22 } 23 idxTree := db.zsetIndex.trees[string(key)] 24 25 scoreBuf := []byte(util.Float64ToStr(score)) 26 zsetKey := db.encodeKey(key, scoreBuf) 27 entry := &logfile.LogEntry{Key: zsetKey, Value: member} 28 pos, err := db.writeLogEntry(entry, ZSet) 29 if err != nil { 30 return err 31 } 32 33 _, size := logfile.EncodeEntry(entry) 34 pos.entrySize = size 35 ent := &logfile.LogEntry{Key: sum, Value: member} 36 if err := db.updateIndexTree(idxTree, ent, pos, true, ZSet); err != nil { 37 return err 38 } 39 db.zsetIndex.indexes.ZAdd(string(key), score, string(sum)) 40 return nil 41 } 42 43 // ZScore returns the score of member in the sorted set at key. 44 func (db *RoseDB) ZScore(key, member []byte) (ok bool, score float64) { 45 db.zsetIndex.mu.RLock() 46 defer db.zsetIndex.mu.RUnlock() 47 48 if err := db.zsetIndex.murhash.Write(member); err != nil { 49 return false, 0 50 } 51 sum := db.zsetIndex.murhash.EncodeSum128() 52 db.zsetIndex.murhash.Reset() 53 return db.zsetIndex.indexes.ZScore(string(key), string(sum)) 54 } 55 56 // ZRem removes the specified members from the sorted set stored at key. Non existing members are ignored. 57 // An error is returned when key exists and does not hold a sorted set. 58 func (db *RoseDB) ZRem(key, member []byte) error { 59 db.zsetIndex.mu.Lock() 60 defer db.zsetIndex.mu.Unlock() 61 62 if err := db.zsetIndex.murhash.Write(member); err != nil { 63 return err 64 } 65 sum := db.zsetIndex.murhash.EncodeSum128() 66 db.zsetIndex.murhash.Reset() 67 68 ok := db.zsetIndex.indexes.ZRem(string(key), string(sum)) 69 if !ok { 70 return nil 71 } 72 73 if db.zsetIndex.trees[string(key)] == nil { 74 db.zsetIndex.trees[string(key)] = art.NewART() 75 } 76 idxTree := db.zsetIndex.trees[string(key)] 77 78 oldVal, deleted := idxTree.Delete(sum) 79 db.sendDiscard(oldVal, deleted, ZSet) 80 entry := &logfile.LogEntry{Key: key, Value: sum, Type: logfile.TypeDelete} 81 pos, err := db.writeLogEntry(entry, ZSet) 82 if err != nil { 83 return err 84 } 85 86 // The deleted entry itself is also invalid. 87 _, size := logfile.EncodeEntry(entry) 88 node := &indexNode{fid: pos.fid, entrySize: size} 89 select { 90 case db.discards[ZSet].valChan <- node: 91 default: 92 logger.Warn("send to discard chan fail") 93 } 94 return nil 95 } 96 97 // ZCard returns the sorted set cardinality (number of elements) of the sorted set stored at key. 98 func (db *RoseDB) ZCard(key []byte) int { 99 db.zsetIndex.mu.RLock() 100 defer db.zsetIndex.mu.RUnlock() 101 return db.zsetIndex.indexes.ZCard(string(key)) 102 } 103 104 // ZRange returns the specified range of elements in the sorted set stored at key. 105 func (db *RoseDB) ZRange(key []byte, start, stop int) ([][]byte, error) { 106 return db.zRangeInternal(key, start, stop, false) 107 } 108 109 // ZRevRange returns the specified range of elements in the sorted set stored at key. 110 // The elements are considered to be ordered from the highest to the lowest score. 111 func (db *RoseDB) ZRevRange(key []byte, start, stop int) ([][]byte, error) { 112 return db.zRangeInternal(key, start, stop, true) 113 } 114 115 // ZRank returns the rank of member in the sorted set stored at key, with the scores ordered from low to high. 116 // The rank (or index) is 0-based, which means that the member with the lowest score has rank 0. 117 func (db *RoseDB) ZRank(key []byte, member []byte) (ok bool, rank int) { 118 return db.zRankInternal(key, member, false) 119 } 120 121 // ZRevRank returns the rank of member in the sorted set stored at key, with the scores ordered from high to low. 122 // The rank (or index) is 0-based, which means that the member with the highest score has rank 0. 123 func (db *RoseDB) ZRevRank(key []byte, member []byte) (ok bool, rank int) { 124 return db.zRankInternal(key, member, true) 125 } 126 127 func (db *RoseDB) zRangeInternal(key []byte, start, stop int, rev bool) ([][]byte, error) { 128 db.zsetIndex.mu.RLock() 129 defer db.zsetIndex.mu.RUnlock() 130 if db.zsetIndex.trees[string(key)] == nil { 131 db.zsetIndex.trees[string(key)] = art.NewART() 132 } 133 idxTree := db.zsetIndex.trees[string(key)] 134 135 var res [][]byte 136 var values []interface{} 137 if rev { 138 values = db.zsetIndex.indexes.ZRevRange(string(key), start, stop) 139 } else { 140 values = db.zsetIndex.indexes.ZRange(string(key), start, stop) 141 } 142 for _, val := range values { 143 v, _ := val.(string) 144 if val, err := db.getVal(idxTree, []byte(v), ZSet); err != nil { 145 return nil, err 146 } else { 147 res = append(res, val) 148 } 149 } 150 return res, nil 151 } 152 153 func (db *RoseDB) zRankInternal(key []byte, member []byte, rev bool) (ok bool, rank int) { 154 db.zsetIndex.mu.RLock() 155 defer db.zsetIndex.mu.RUnlock() 156 if db.zsetIndex.trees[string(key)] == nil { 157 return 158 } 159 160 if err := db.zsetIndex.murhash.Write(member); err != nil { 161 return 162 } 163 sum := db.zsetIndex.murhash.EncodeSum128() 164 db.zsetIndex.murhash.Reset() 165 166 var result int64 167 if rev { 168 result = db.zsetIndex.indexes.ZRevRank(string(key), string(sum)) 169 } else { 170 result = db.zsetIndex.indexes.ZRank(string(key), string(sum)) 171 } 172 if result != -1 { 173 ok = true 174 rank = int(result) 175 } 176 return 177 }