github.com/flower-corp/rosedb@v1.1.2-0.20230117132829-21dc4f7b319a/ds/zset/zset.go (about)

     1  package zset
     2  
     3  import (
     4  	"math"
     5  	"math/rand"
     6  
     7  	"github.com/flower-corp/rosedb/logfile"
     8  	"github.com/flower-corp/rosedb/util"
     9  )
    10  
    11  // zset is the implementation of sorted set
    12  
    13  const (
    14  	maxLevel    = 32
    15  	probability = 0.25
    16  )
    17  
    18  type EncodeKey func(key, subKey []byte) []byte
    19  
    20  type (
    21  	// SortedSet sorted set struct
    22  	SortedSet struct {
    23  		record map[string]*SortedSetNode
    24  	}
    25  
    26  	// SortedSetNode node of sorted set
    27  	SortedSetNode struct {
    28  		dict map[string]*sklNode
    29  		skl  *skipList
    30  	}
    31  
    32  	sklLevel struct {
    33  		forward *sklNode
    34  		span    uint64
    35  	}
    36  
    37  	sklNode struct {
    38  		member   string
    39  		score    float64
    40  		backward *sklNode
    41  		level    []*sklLevel
    42  	}
    43  
    44  	skipList struct {
    45  		head   *sklNode
    46  		tail   *sklNode
    47  		length int64
    48  		level  int16
    49  	}
    50  )
    51  
    52  // New create a new sorted set.
    53  func New() *SortedSet {
    54  	return &SortedSet{
    55  		make(map[string]*SortedSetNode),
    56  	}
    57  }
    58  
    59  func (z *SortedSet) IterateAndSend(chn chan *logfile.LogEntry, encode EncodeKey) {
    60  	for key, ss := range z.record {
    61  		zsetKey := []byte(key)
    62  		if ss.skl.head == nil {
    63  			return
    64  		}
    65  		for e := ss.skl.head.level[0].forward; e != nil; e = e.level[0].forward {
    66  			scoreBuf := []byte(util.Float64ToStr(e.score))
    67  			encKey := encode(zsetKey, scoreBuf)
    68  			chn <- &logfile.LogEntry{Key: encKey, Value: []byte(e.member)}
    69  		}
    70  	}
    71  	return
    72  }
    73  
    74  // ZAdd Adds the specified member with the specified score to the sorted set stored at key.
    75  func (z *SortedSet) ZAdd(key string, score float64, member string) {
    76  	if !z.exist(key) {
    77  
    78  		node := &SortedSetNode{
    79  			dict: make(map[string]*sklNode),
    80  			skl:  newSkipList(),
    81  		}
    82  		z.record[key] = node
    83  	}
    84  
    85  	item := z.record[key]
    86  	v, exist := item.dict[member]
    87  
    88  	var node *sklNode
    89  	if exist {
    90  		if score != v.score {
    91  			item.skl.sklDelete(v.score, member)
    92  			node = item.skl.sklInsert(score, member)
    93  		}
    94  	} else {
    95  		node = item.skl.sklInsert(score, member)
    96  	}
    97  
    98  	if node != nil {
    99  		item.dict[member] = node
   100  	}
   101  }
   102  
   103  // ZScore returns the score of member in the sorted set at key.
   104  func (z *SortedSet) ZScore(key string, member string) (ok bool, score float64) {
   105  	if !z.exist(key) {
   106  		return
   107  	}
   108  
   109  	node, exist := z.record[key].dict[member]
   110  	if !exist {
   111  		return
   112  	}
   113  
   114  	return true, node.score
   115  }
   116  
   117  // ZCard returns the sorted set cardinality (number of elements) of the sorted set stored at key.
   118  func (z *SortedSet) ZCard(key string) int {
   119  	if !z.exist(key) {
   120  		return 0
   121  	}
   122  
   123  	return len(z.record[key].dict)
   124  }
   125  
   126  // ZRank returns the rank of member in the sorted set stored at key, with the scores ordered from low to high.
   127  // The rank (or index) is 0-based, which means that the member with the lowest score has rank 0.
   128  func (z *SortedSet) ZRank(key, member string) int64 {
   129  	if !z.exist(key) {
   130  		return -1
   131  	}
   132  
   133  	v, exist := z.record[key].dict[member]
   134  	if !exist {
   135  		return -1
   136  	}
   137  
   138  	rank := z.record[key].skl.sklGetRank(v.score, member)
   139  	rank--
   140  
   141  	return rank
   142  }
   143  
   144  // ZRevRank returns the rank of member in the sorted set stored at key, with the scores ordered from high to low.
   145  // The rank (or index) is 0-based, which means that the member with the highest score has rank 0.
   146  func (z *SortedSet) ZRevRank(key, member string) int64 {
   147  	if !z.exist(key) {
   148  		return -1
   149  	}
   150  
   151  	v, exist := z.record[key].dict[member]
   152  	if !exist {
   153  		return -1
   154  	}
   155  
   156  	rank := z.record[key].skl.sklGetRank(v.score, member)
   157  
   158  	return z.record[key].skl.length - rank
   159  }
   160  
   161  // ZIncrBy increments the score of member in the sorted set stored at key by increment.
   162  // If member does not exist in the sorted set, it is added with increment as its score (as if its previous score was 0.0).
   163  // If key does not exist, a new sorted set with the specified member as its sole member is created.
   164  func (z *SortedSet) ZIncrBy(key string, increment float64, member string) float64 {
   165  	if z.exist(key) {
   166  		node, exist := z.record[key].dict[member]
   167  		if exist {
   168  			increment += node.score
   169  		}
   170  	}
   171  
   172  	z.ZAdd(key, increment, member)
   173  	return increment
   174  }
   175  
   176  // ZRange returns the specified range of elements in the sorted set stored at <key>.
   177  func (z *SortedSet) ZRange(key string, start, stop int) []interface{} {
   178  	if !z.exist(key) {
   179  		return nil
   180  	}
   181  
   182  	return z.findRange(key, int64(start), int64(stop), false, false)
   183  }
   184  
   185  // ZRangeWithScores returns the specified range of elements in the sorted set stored at <key>.
   186  func (z *SortedSet) ZRangeWithScores(key string, start, stop int) []interface{} {
   187  	if !z.exist(key) {
   188  		return nil
   189  	}
   190  
   191  	return z.findRange(key, int64(start), int64(stop), false, true)
   192  }
   193  
   194  // ZRevRange returns the specified range of elements in the sorted set stored at key.
   195  // The elements are considered to be ordered from the highest to the lowest score.
   196  // Descending lexicographical order is used for elements with equal score.
   197  func (z *SortedSet) ZRevRange(key string, start, stop int) []interface{} {
   198  	if !z.exist(key) {
   199  		return nil
   200  	}
   201  
   202  	return z.findRange(key, int64(start), int64(stop), true, false)
   203  }
   204  
   205  // ZRevRangeWithScores returns the specified range of elements in the sorted set stored at key.
   206  // The elements are considered to be ordered from the highest to the lowest score.
   207  // Descending lexicographical order is used for elements with equal score.
   208  func (z *SortedSet) ZRevRangeWithScores(key string, start, stop int) []interface{} {
   209  	if !z.exist(key) {
   210  		return nil
   211  	}
   212  
   213  	return z.findRange(key, int64(start), int64(stop), true, true)
   214  }
   215  
   216  // ZRem removes the specified members from the sorted set stored at key. Non existing members are ignored.
   217  // An error is returned when key exists and does not hold a sorted set.
   218  func (z *SortedSet) ZRem(key, member string) bool {
   219  	if !z.exist(key) {
   220  		return false
   221  	}
   222  
   223  	v, exist := z.record[key].dict[member]
   224  	if exist {
   225  		z.record[key].skl.sklDelete(v.score, member)
   226  		delete(z.record[key].dict, member)
   227  		return true
   228  	}
   229  
   230  	return false
   231  }
   232  
   233  // ZGetByRank get the member at key by rank, the rank is ordered from lowest to highest.
   234  // The rank of lowest is 0 and so on.
   235  func (z *SortedSet) ZGetByRank(key string, rank int) (val []interface{}) {
   236  	if !z.exist(key) {
   237  		return
   238  	}
   239  
   240  	member, score := z.getByRank(key, int64(rank), false)
   241  	val = append(val, member, score)
   242  	return
   243  }
   244  
   245  // ZRevGetByRank get the member at key by rank, the rank is ordered from highest to lowest.
   246  // The rank of highest is 0 and so on.
   247  func (z *SortedSet) ZRevGetByRank(key string, rank int) (val []interface{}) {
   248  	if !z.exist(key) {
   249  		return
   250  	}
   251  
   252  	member, score := z.getByRank(key, int64(rank), true)
   253  	val = append(val, member, score)
   254  	return
   255  }
   256  
   257  // ZScoreRange returns all the elements in the sorted set at key with a score between min and max (including elements with score equal to min or max).
   258  // The elements are considered to be ordered from low to high scores.
   259  func (z *SortedSet) ZScoreRange(key string, min, max float64) (val []interface{}) {
   260  	if !z.exist(key) || min > max {
   261  		return
   262  	}
   263  
   264  	item := z.record[key].skl
   265  	minScore := item.head.level[0].forward.score
   266  	if min < minScore {
   267  		min = minScore
   268  	}
   269  
   270  	maxScore := item.tail.score
   271  	if max > maxScore {
   272  		max = maxScore
   273  	}
   274  
   275  	p := item.head
   276  	for i := item.level - 1; i >= 0; i-- {
   277  		for p.level[i].forward != nil && p.level[i].forward.score < min {
   278  			p = p.level[i].forward
   279  		}
   280  	}
   281  
   282  	p = p.level[0].forward
   283  	for p != nil {
   284  		if p.score > max {
   285  			break
   286  		}
   287  
   288  		val = append(val, p.member, p.score)
   289  		p = p.level[0].forward
   290  	}
   291  
   292  	return
   293  }
   294  
   295  // ZRevScoreRange returns all the elements in the sorted set at key with a score between max and min (including elements with score equal to max or min).
   296  // In contrary to the default ordering of sorted sets, for this command the elements are considered to be ordered from high to low scores.
   297  func (z *SortedSet) ZRevScoreRange(key string, max, min float64) (val []interface{}) {
   298  	if !z.exist(key) || max < min {
   299  		return
   300  	}
   301  
   302  	item := z.record[key].skl
   303  	minScore := item.head.level[0].forward.score
   304  	if min < minScore {
   305  		min = minScore
   306  	}
   307  
   308  	maxScore := item.tail.score
   309  	if max > maxScore {
   310  		max = maxScore
   311  	}
   312  
   313  	p := item.head
   314  	for i := item.level - 1; i >= 0; i-- {
   315  		for p.level[i].forward != nil && p.level[i].forward.score <= max {
   316  			p = p.level[i].forward
   317  		}
   318  	}
   319  
   320  	for p != nil {
   321  		if p.score < min {
   322  			break
   323  		}
   324  
   325  		val = append(val, p.member, p.score)
   326  		p = p.backward
   327  	}
   328  
   329  	return
   330  }
   331  
   332  // ZKeyExists check if the key exists in zset.
   333  func (z *SortedSet) ZKeyExists(key string) bool {
   334  	return z.exist(key)
   335  }
   336  
   337  // ZClear clear the key in zset.
   338  func (z *SortedSet) ZClear(key string) {
   339  	if z.ZKeyExists(key) {
   340  		delete(z.record, key)
   341  	}
   342  }
   343  
   344  func (z *SortedSet) exist(key string) bool {
   345  	_, exist := z.record[key]
   346  	return exist
   347  }
   348  
   349  func (z *SortedSet) getByRank(key string, rank int64, reverse bool) (string, float64) {
   350  
   351  	skl := z.record[key].skl
   352  	if rank < 0 || rank > skl.length {
   353  		return "", math.MinInt64
   354  	}
   355  
   356  	if reverse {
   357  		rank = skl.length - rank
   358  	} else {
   359  		rank++
   360  	}
   361  
   362  	n := skl.sklGetElementByRank(uint64(rank))
   363  	if n == nil {
   364  		return "", math.MinInt64
   365  	}
   366  
   367  	node := z.record[key].dict[n.member]
   368  	if node == nil {
   369  		return "", math.MinInt64
   370  	}
   371  
   372  	return node.member, node.score
   373  }
   374  
   375  func (z *SortedSet) findRange(key string, start, stop int64, reverse bool, withScores bool) (val []interface{}) {
   376  	skl := z.record[key].skl
   377  	length := skl.length
   378  
   379  	if start < 0 {
   380  		start += length
   381  		if start < 0 {
   382  			start = 0
   383  		}
   384  	}
   385  
   386  	if stop < 0 {
   387  		stop += length
   388  	}
   389  
   390  	if start > stop || start >= length {
   391  		return
   392  	}
   393  
   394  	if stop >= length {
   395  		stop = length - 1
   396  	}
   397  	span := (stop - start) + 1
   398  
   399  	var node *sklNode
   400  	if reverse {
   401  		node = skl.tail
   402  		if start > 0 {
   403  			node = skl.sklGetElementByRank(uint64(length - start))
   404  		}
   405  	} else {
   406  		node = skl.head.level[0].forward
   407  		if start > 0 {
   408  			node = skl.sklGetElementByRank(uint64(start + 1))
   409  		}
   410  	}
   411  
   412  	for span > 0 {
   413  		span--
   414  		if withScores {
   415  			val = append(val, node.member, node.score)
   416  		} else {
   417  			val = append(val, node.member)
   418  		}
   419  		if reverse {
   420  			node = node.backward
   421  		} else {
   422  			node = node.level[0].forward
   423  		}
   424  	}
   425  
   426  	return
   427  }
   428  
   429  func sklNewNode(level int16, score float64, member string) *sklNode {
   430  	node := &sklNode{
   431  		score:  score,
   432  		member: member,
   433  		level:  make([]*sklLevel, level),
   434  	}
   435  
   436  	for i := range node.level {
   437  		node.level[i] = new(sklLevel)
   438  	}
   439  
   440  	return node
   441  }
   442  
   443  func newSkipList() *skipList {
   444  	return &skipList{
   445  		level: 1,
   446  		head:  sklNewNode(maxLevel, 0, ""),
   447  	}
   448  }
   449  
   450  func randomLevel() int16 {
   451  	var level int16 = 1
   452  	for level < maxLevel {
   453  		if rand.Float64() < probability {
   454  			break
   455  		}
   456  		level++
   457  	}
   458  	return level
   459  }
   460  
   461  func (skl *skipList) sklInsert(score float64, member string) *sklNode {
   462  	updates := make([]*sklNode, maxLevel)
   463  	rank := make([]uint64, maxLevel)
   464  
   465  	p := skl.head
   466  	for i := skl.level - 1; i >= 0; i-- {
   467  		if i == skl.level-1 {
   468  			rank[i] = 0
   469  		} else {
   470  			rank[i] = rank[i+1]
   471  		}
   472  
   473  		if p.level[i] != nil {
   474  			for p.level[i].forward != nil &&
   475  				(p.level[i].forward.score < score ||
   476  					(p.level[i].forward.score == score && p.level[i].forward.member < member)) {
   477  
   478  				rank[i] += p.level[i].span
   479  				p = p.level[i].forward
   480  			}
   481  		}
   482  		updates[i] = p
   483  	}
   484  
   485  	level := randomLevel()
   486  	if level > skl.level {
   487  		for i := skl.level; i < level; i++ {
   488  			rank[i] = 0
   489  			updates[i] = skl.head
   490  			updates[i].level[i].span = uint64(skl.length)
   491  		}
   492  		skl.level = level
   493  	}
   494  
   495  	p = sklNewNode(level, score, member)
   496  	for i := int16(0); i < level; i++ {
   497  		p.level[i].forward = updates[i].level[i].forward
   498  		updates[i].level[i].forward = p
   499  
   500  		p.level[i].span = updates[i].level[i].span - (rank[0] - rank[i])
   501  		updates[i].level[i].span = (rank[0] - rank[i]) + 1
   502  	}
   503  
   504  	for i := level; i < skl.level; i++ {
   505  		updates[i].level[i].span++
   506  	}
   507  
   508  	if updates[0] == skl.head {
   509  		p.backward = nil
   510  	} else {
   511  		p.backward = updates[0]
   512  	}
   513  
   514  	if p.level[0].forward != nil {
   515  		p.level[0].forward.backward = p
   516  	} else {
   517  		skl.tail = p
   518  	}
   519  
   520  	skl.length++
   521  	return p
   522  }
   523  
   524  func (skl *skipList) sklDeleteNode(p *sklNode, updates []*sklNode) {
   525  	for i := int16(0); i < skl.level; i++ {
   526  		if updates[i].level[i].forward == p {
   527  			updates[i].level[i].span += p.level[i].span - 1
   528  			updates[i].level[i].forward = p.level[i].forward
   529  		} else {
   530  			updates[i].level[i].span--
   531  		}
   532  	}
   533  
   534  	if p.level[0].forward != nil {
   535  		p.level[0].forward.backward = p.backward
   536  	} else {
   537  		skl.tail = p.backward
   538  	}
   539  
   540  	for skl.level > 1 && skl.head.level[skl.level-1].forward == nil {
   541  		skl.level--
   542  	}
   543  
   544  	skl.length--
   545  }
   546  
   547  func (skl *skipList) sklDelete(score float64, member string) {
   548  	update := make([]*sklNode, maxLevel)
   549  	p := skl.head
   550  
   551  	for i := skl.level - 1; i >= 0; i-- {
   552  		for p.level[i].forward != nil &&
   553  			(p.level[i].forward.score < score ||
   554  				(p.level[i].forward.score == score && p.level[i].forward.member < member)) {
   555  			p = p.level[i].forward
   556  		}
   557  		update[i] = p
   558  	}
   559  
   560  	p = p.level[0].forward
   561  	if p != nil && score == p.score && p.member == member {
   562  		skl.sklDeleteNode(p, update)
   563  		return
   564  	}
   565  }
   566  
   567  func (skl *skipList) sklGetRank(score float64, member string) int64 {
   568  	var rank uint64 = 0
   569  	p := skl.head
   570  
   571  	for i := skl.level - 1; i >= 0; i-- {
   572  		for p.level[i].forward != nil &&
   573  			(p.level[i].forward.score < score ||
   574  				(p.level[i].forward.score == score && p.level[i].forward.member <= member)) {
   575  
   576  			rank += p.level[i].span
   577  			p = p.level[i].forward
   578  		}
   579  
   580  		if p.member == member {
   581  			return int64(rank)
   582  		}
   583  	}
   584  
   585  	return 0
   586  }
   587  
   588  func (skl *skipList) sklGetElementByRank(rank uint64) *sklNode {
   589  	var traversed uint64 = 0
   590  	p := skl.head
   591  
   592  	for i := skl.level - 1; i >= 0; i-- {
   593  		for p.level[i].forward != nil && (traversed+p.level[i].span) <= rank {
   594  			traversed += p.level[i].span
   595  			p = p.level[i].forward
   596  		}
   597  		if traversed == rank {
   598  			return p
   599  		}
   600  	}
   601  
   602  	return nil
   603  }