perf(skiplist): perf list pop left, pop range

This commit is contained in:
bandl 2021-10-18 23:58:11 +08:00
parent 064ef3e50e
commit ac8f748356
1 changed files with 101 additions and 21 deletions

View File

@ -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
}