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 }