diff --git a/pkg/util/skiplist/skiplist.go b/pkg/util/skiplist/skiplist.go index 391f559..34aaeb2 100644 --- a/pkg/util/skiplist/skiplist.go +++ b/pkg/util/skiplist/skiplist.go @@ -166,40 +166,120 @@ func (s *SkipList) RemoveAll(score float64) { s.delSkipListNode(delNode...) } -// ClearLeft 删除 小等于 score 的全部节点 -func (s *SkipList) ClearLeft(score float64) *skipListNode { +func (s *SkipList) PopLeft(score float64) []interface{} { + endPoint := s.tail + head := s.head - for head.down != nil { - p := head - for p.score <= score { - p = p.next + for endPoint.score > score { + endPoint = endPoint.pre + } + + var valuePoint *skipListNode + for endPoint != nil { + // 检查 end 后的节点情况 + for endPoint.next.score <= score { + endPoint = endPoint.next } - head.next = p - p.pre = head + head.next = endPoint.next + endPoint.next.pre = head + valuePoint = endPoint + + endPoint = endPoint.down head = head.down } - node := s.searchNode(score) - for node.score <= score { - node = node.next + values := make([]interface{}, 0, 100) + for valuePoint != nil && valuePoint.score > s.head.score { + values = append(values, valuePoint.val) + valuePoint = valuePoint.pre } - oldNode := node.pre - head.next = node + return values - node.pre = head - return oldNode } -func (s *SkipList) PopLeft(score float64) []interface{} { - node := s.ClearLeft(score) - values := make([]interface{}, 0, 10) - for node.score != math.MinInt64 { - values = append(values, node.val) - node = node.pre +func (s *SkipList) PopRight(score float64) []interface{} { + startPoint := s.head + + tail := s.tail + + for startPoint.score < score { + startPoint = startPoint.next } + + var valuePoint *skipListNode + for startPoint != nil { + // 检查 end 后的节点情况 + for startPoint.pre.score >= score { + startPoint = startPoint.pre + } + + tail.pre = startPoint.pre + startPoint.pre.next = tail + valuePoint = startPoint + + startPoint = startPoint.down + tail = tail.down + } + + values := make([]interface{}, 0, 100) + for valuePoint != nil && valuePoint.score < s.tail.score { + values = append(values, valuePoint.val) + valuePoint = valuePoint.next + } + + return values + +} + +// PopRangeByScore 删除包括 start 到 end 的 score 的全部 value +func (s *SkipList) PopRangeByScore(startScore float64, endScore float64) []interface{} { + if startScore >= endScore { + return nil + } + + startPoint := s.head + endPoint := s.tail + + // 定位删除索引最高级 + for startPoint.score < startScore { + startPoint = startPoint.next + } + for endPoint.score > endScore { + endPoint = endPoint.pre + } + + var valuePoint *skipListNode + + for startPoint != nil { + // 检查 start 前的节点情况 + for startPoint.pre.score >= startScore { + startPoint = startPoint.pre + } + + // 检查 end 后的节点情况 + for endPoint.next.score <= endScore { + endPoint = endPoint.next + } + + // 删除节点 + valuePoint = startPoint + startPoint.pre.next = endPoint.next + endPoint.next.pre = startPoint.pre + + // 下一级处理 + startPoint = startPoint.down + endPoint = endPoint.down + } + + values := make([]interface{}, 0, 100) + for valuePoint != nil && valuePoint.score <= endScore { + values = append(values, valuePoint.val) + valuePoint = valuePoint.next + } + return values }