github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/container/sortlist/list/sorted_list.go (about)

     1  package list
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"sync"
     7  	"time"
     8  )
     9  
    10  const (
    11  	N_INF = "-inf"
    12  	P_INF = "+inf"
    13  )
    14  
    15  type SortedList struct {
    16  	list *List
    17  	lock sync.RWMutex
    18  	// 创建时间 unix timestamp in second
    19  	createTime int64
    20  }
    21  
    22  func NewSortedList() *SortedList {
    23  	return new(SortedList).Init()
    24  }
    25  
    26  func (sl *SortedList) Init() *SortedList {
    27  	sl.list = New()
    28  	sl.createTime = time.Now().Unix()
    29  	return sl
    30  }
    31  
    32  func (sl *SortedList) Len() int {
    33  	sl.lock.RLock()
    34  	defer sl.lock.RUnlock()
    35  	return sl.list.Len()
    36  }
    37  
    38  // 返回链表创建时间
    39  func (sl *SortedList) CreateTime() int64 {
    40  	sl.lock.RLock()
    41  	defer sl.lock.RUnlock()
    42  	return sl.createTime
    43  }
    44  
    45  // Front returns the first element of list l or nil if the list is empty.
    46  func (sl *SortedList) Front() *Element {
    47  	sl.lock.RLock()
    48  	defer sl.lock.RUnlock()
    49  	return sl.list.Front()
    50  }
    51  
    52  // Back returns the last element of list l or nil if the list is empty.
    53  func (sl *SortedList) Back() *Element {
    54  	sl.lock.RLock()
    55  	defer sl.lock.RUnlock()
    56  	return sl.list.Back()
    57  }
    58  
    59  func (sl *SortedList) Range(start int, stop int) []*Element {
    60  	if sl.Len() <= 0 {
    61  		return nil
    62  	}
    63  	if offset, count, err := sl.parseLimit(start, stop); err != nil {
    64  		return nil
    65  	} else {
    66  		sl.lock.RLock()
    67  		defer sl.lock.RUnlock()
    68  		return sl.list.Range(offset, count)
    69  	}
    70  }
    71  
    72  func (sl *SortedList) RangeByScore(min string, max string) []*Element {
    73  	if sl.Len() <= 0 {
    74  		return nil
    75  	}
    76  	if minRes, maxRes, err := sl.parseScoreLimit(min, max); err != nil {
    77  		return nil
    78  	} else {
    79  		sl.lock.RLock()
    80  		defer sl.lock.RUnlock()
    81  		return sl.list.RangeByScore(minRes, maxRes)
    82  	}
    83  }
    84  
    85  func (sl *SortedList) AddBatch(values [][]byte) error {
    86  	if len(values)%2 != 0 {
    87  		return errors.New("param error")
    88  	}
    89  	sl.lock.Lock()
    90  	defer sl.lock.Unlock()
    91  	for i := 0; i < len(values); i += 2 {
    92  		sl.add(values[i], values[i+1])
    93  	}
    94  	return nil
    95  }
    96  
    97  func (sl *SortedList) add(value interface{}, score []byte) {
    98  
    99  	if llen := sl.list.len; llen <= 0 {
   100  		sl.list.PushFront(value, score)
   101  	} else {
   102  		first := sl.list.Front()
   103  		if compareScore(score, first.Score) < 0 {
   104  			// 插入为第一个节点
   105  			sl.list.InsertBefore(value, score, first)
   106  		} else {
   107  			// 从后往前遍历
   108  			location := sl.list.Back()
   109  			for ; compareScore(score, location.Score) < 0; location = location.Prev() {
   110  				// 什么都不做
   111  			}
   112  			// 已遍历一遍到头
   113  			sl.list.InsertAfter(value, score, location)
   114  		}
   115  	}
   116  }
   117  
   118  // 分析start及stop
   119  // return: offset 从头到尾的偏移量,大于0
   120  // 		   count 数目,大于0
   121  func (sl *SortedList) parseLimit(start int, stop int) (offset int, count int, err error) {
   122  	llen := sl.Len()
   123  	if start < 0 {
   124  		// 转为正数的start
   125  		if start = llen + start; start < 0 {
   126  			start = 0
   127  		}
   128  	}
   129  	if stop < 0 {
   130  		stop = llen + stop
   131  	} else if stop > llen-1 {
   132  		// 若stop参数值比list最大下标还要大,将stop作为list的最大下标来处理
   133  		stop = llen - 1
   134  	}
   135  	if start > llen || start > stop {
   136  		err = errors.New("invalid start or stop")
   137  		return
   138  	}
   139  
   140  	if start < 0 || stop < 0 {
   141  		err = errors.New("invalid start or stop")
   142  		return
   143  	}
   144  
   145  	offset = start
   146  	count = (stop - start) + 1
   147  	return
   148  }
   149  
   150  func (sl *SortedList) parseScoreLimit(min string, max string) (minRes string, maxRes string, err error) {
   151  	frontScore := string(sl.Front().Score)
   152  	backScore := string(sl.Back().Score)
   153  	if min == N_INF {
   154  		min = frontScore
   155  	}
   156  	if max == P_INF {
   157  		max = backScore
   158  	}
   159  	if min < max {
   160  		err = errors.New("invalid min or max")
   161  		return
   162  	}
   163  	if min < frontScore {
   164  		minRes = frontScore
   165  	}
   166  	if max > backScore {
   167  		maxRes = backScore
   168  	}
   169  	return
   170  }
   171  
   172  // 比较 a、b 的score值
   173  // The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
   174  func compareScore(a, b []byte) int {
   175  	if len(a) > len(b) {
   176  		return 1
   177  	} else if len(a) < len(b) {
   178  		return -1
   179  	} else {
   180  		return bytes.Compare(a, b)
   181  	}
   182  }