109 lines
2.3 KiB
Go
109 lines
2.3 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 PointCache struct {
|
||
sync.RWMutex
|
||
M map[string]*SafeLinkedList
|
||
}
|
||
|
||
func NewPointCache() *PointCache {
|
||
return &PointCache{M: make(map[string]*SafeLinkedList)}
|
||
}
|
||
|
||
func (pc *PointCache) Get(key string) (*SafeLinkedList, bool) {
|
||
pc.RLock()
|
||
defer pc.RUnlock()
|
||
val, ok := pc.M[key]
|
||
return val, ok
|
||
}
|
||
|
||
func (pc *PointCache) Set(key string, val *SafeLinkedList) {
|
||
pc.Lock()
|
||
defer pc.Unlock()
|
||
pc.M[key] = val
|
||
}
|
||
|
||
func (pc *PointCache) Len() int {
|
||
pc.RLock()
|
||
defer pc.RUnlock()
|
||
return len(pc.M)
|
||
}
|
||
|
||
func (pc *PointCache) CleanStale(before int64) {
|
||
keys := []string{}
|
||
|
||
pc.RLock()
|
||
for key, L := range pc.M {
|
||
front := L.Front()
|
||
if front == nil {
|
||
continue
|
||
}
|
||
|
||
if front.Value.(*vos.MetricPoint).Time < before {
|
||
keys = append(keys, key)
|
||
}
|
||
}
|
||
pc.RUnlock()
|
||
|
||
pc.BatchDelete(keys)
|
||
}
|
||
|
||
func (pc *PointCache) BatchDelete(keys []string) {
|
||
count := len(keys)
|
||
if count == 0 {
|
||
return
|
||
}
|
||
|
||
pc.Lock()
|
||
defer pc.Unlock()
|
||
for i := 0; i < count; i++ {
|
||
delete(pc.M, keys[i])
|
||
}
|
||
}
|
||
|
||
func (pc *PointCache) PutPoint(p *vos.MetricPoint, maxAliveDuration int64) *SafeLinkedList {
|
||
linkedList, exists := pc.Get(p.PK)
|
||
if exists {
|
||
linkedList.PushFrontAndMaintain(p, maxAliveDuration)
|
||
} else {
|
||
NL := list.New()
|
||
NL.PushFront(p)
|
||
linkedList = &SafeLinkedList{L: NL}
|
||
pc.Set(p.PK, linkedList)
|
||
}
|
||
|
||
return linkedList
|
||
}
|
||
|
||
// 这是个线程不安全的大Map,需要提前初始化好
|
||
var PointCaches = make(map[string]*PointCache)
|
||
|
||
func initPointCaches() {
|
||
arr := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}
|
||
for i := 0; i < 16; i++ {
|
||
for j := 0; j < 16; j++ {
|
||
PointCaches[arr[i]+arr[j]] = NewPointCache()
|
||
}
|
||
}
|
||
}
|