nightingale/judge/linkedlist.go

165 lines
3.4 KiB
Go
Raw Normal View History

// Copyright 2017 Xiaomi, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package judge
import (
"container/list"
"sync"
"github.com/didi/nightingale/v5/vos"
)
type SafeLinkedList struct {
sync.RWMutex
L *list.List
}
func (ll *SafeLinkedList) Front() *list.Element {
ll.RLock()
defer ll.RUnlock()
return ll.L.Front()
}
func (ll *SafeLinkedList) Len() int {
ll.RLock()
defer ll.RUnlock()
return ll.L.Len()
}
func (ll *SafeLinkedList) PushFrontAndMaintain(v *vos.MetricPoint, maintainDuration int64) {
ll.Lock()
defer ll.Unlock()
sz := ll.L.Len()
lastPointTs := ll.L.Front().Value.(*vos.MetricPoint).Time
earliestTs := v.Time - maintainDuration
if sz > 0 {
// 新push上来的数据有可能重复了或者timestamp不对这种数据要丢掉
if v.Time <= lastPointTs {
return
}
}
ll.L.PushFront(v)
sz++
for i := 0; i < sz; i++ {
if ll.L.Back().Value.(*vos.MetricPoint).Time >= earliestTs {
break
}
//最前面的点已经不在告警策略时间周期内,丢弃掉
ll.L.Remove(ll.L.Back())
}
}
func (ll *SafeLinkedList) HistoryPoints(smallestTime int64) []*vos.HPoint {
size := ll.Len()
if size == 0 {
return []*vos.HPoint{}
}
firstElement := ll.Front()
firstItem := firstElement.Value.(*vos.MetricPoint)
vs := make([]*vos.HPoint, 0)
if firstItem.Time < smallestTime {
return vs
}
v := &vos.HPoint{
Timestamp: firstItem.Time,
Value: vos.JsonFloat(firstItem.Value),
}
vs = append(vs, v)
currentElement := firstElement
for i := 1; i < size; i++ {
nextElement := currentElement.Next()
if nextElement == nil {
return vs
}
item := nextElement.Value.(*vos.MetricPoint)
if item.Time < smallestTime {
return vs
}
v := &vos.HPoint{
Timestamp: item.Time,
Value: vos.JsonFloat(item.Value),
}
vs = append(vs, v)
currentElement = nextElement
}
return vs
}
// func (ll *SafeLinkedList) QueryDataByTS(start, end int64) []*vos.HPoint {
// size := ll.Len()
// if size == 0 {
// return []*vos.HPoint{}
// }
// firstElement := ll.Front()
// firstItem := firstElement.Value.(*vos.MetricPoint)
// var vs []*vos.HPoint
// if firstItem.Time < start {
// //最新的点也比起始时间旧,直接返回
// return vs
// }
// v := &vos.HPoint{
// Timestamp: firstItem.Time,
// Value: vos.JsonFloat(firstItem.Value),
// }
// vs = append(vs, v)
// currentElement := firstElement
// for {
// nextElement := currentElement.Next()
// if nextElement == nil {
// return vs
// }
// if nextElement.Value.(*vos.MetricPoint).Time < start {
// return vs
// }
// if nextElement.Value.(*vos.MetricPoint).Time > end {
// currentElement = nextElement
// continue
// }
// v := &vos.HPoint{
// Timestamp: nextElement.Value.(*vos.MetricPoint).Time,
// Value: vos.JsonFloat(nextElement.Value.(*vos.MetricPoint).Value),
// }
// vs = append(vs, v)
// currentElement = nextElement
// }
// return vs
// }