pkg/profiling/task/network/analyze/layer7/protocols/metrics/topn.go (66 lines of code) (raw):

// Licensed to Apache Software Foundation (ASF) under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Apache Software Foundation (ASF) licenses this file to you 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 metrics import ( "container/list" "github.com/apache/skywalking-rover/pkg/process/api" "github.com/apache/skywalking-rover/pkg/profiling/task/network/analyze/base" ) type TopN struct { MaxLength int List *list.List } type TopNData interface { Flush(duration int64, process api.ProcessInterface, traffic *base.ProcessTraffic, metricsBuilder *base.MetricsBuilder) } type TopNRecord struct { Duration int64 Data TopNData } func NewTopN(length int) *TopN { return &TopN{ MaxLength: length, List: list.New(), } } func (t *TopN) AddRecord(data TopNData, duration int64) { // don't need to be added if the duration is lower than the latest value if t.List.Len() >= t.MaxLength && t.List.Back().Value.(*TopNRecord).Duration > duration { return } node := t.createNode(data, duration) if t.List.Len() == 0 { t.List.PushFront(node) return } // insert to the list added := false for element := t.List.Back(); element != nil; element = element.Prev() { if element.Value.(*TopNRecord).Duration < duration { t.List.InsertBefore(node, element) added = true break } } if !added { t.List.PushBack(node) } // remove latest value if t.List.Len() > t.MaxLength { t.List.Remove(t.List.Back()) } } func (t *TopN) MergeAndClean(other *TopN) { for element := other.List.Front(); element != nil; element = element.Next() { record := element.Value.(*TopNRecord) t.AddRecord(record.Data, record.Duration) } other.List.Init() } func (t *TopN) AppendData(process api.ProcessInterface, traffic *base.ProcessTraffic, metricsBuilder *base.MetricsBuilder) int { result := 0 for element := t.List.Front(); element != nil; element = element.Next() { record := element.Value.(*TopNRecord) record.Data.Flush(record.Duration, process, traffic, metricsBuilder) result++ } return result } func (t *TopN) createNode(data TopNData, duration int64) *TopNRecord { return &TopNRecord{Data: data, Duration: duration} }