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  }