165 lines
3.4 KiB
Go
165 lines
3.4 KiB
Go
// 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
|
||
// }
|