-
Notifications
You must be signed in to change notification settings - Fork 5.5k
/
filtering.go
179 lines (168 loc) · 5.55 KB
/
filtering.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//go:build linux && amd64
package intel_pmt
import (
"errors"
"regexp"
"slices"
)
var metricPatternRegex = regexp.MustCompile(`(?P<class>(C|CHA))\d+_(?P<var>[A-Z0-9_]+)$`)
// verifyNoEmpty checks if all pmt XMLs are not empty.
//
// Data for different GUIDs can be empty
// but data for at least one GUID cannot be empty.
//
// Returns:
// - nil if at least one pair of XMLs for GUID is not empty.
// - an error if all XMLs are empty.
func (p *IntelPMT) verifyNoEmpty() error {
emptyAggInterface := true
for guid := range p.pmtTelemetryFiles {
if len(p.pmtAggregatorInterface[guid].AggregatorSamples.AggregatorSample) != 0 {
emptyAggInterface = false
break
}
}
if emptyAggInterface {
return errors.New("all aggregator interface XMLs are empty")
}
emptyAgg := true
for guid := range p.pmtTelemetryFiles {
if len(p.pmtAggregator[guid].SampleGroup) != 0 {
emptyAgg = false
break
}
}
if emptyAgg {
return errors.New("all aggregator XMLs are empty")
}
return nil
}
// filterAggregatorByDatatype filters Aggregator XML by provided datatypes.
//
// Every sample group in aggregator XML consists of several samples.
// Every sample in the group has a datatype assigned.
// This function filters the samples based on their datatype.
//
// Parameters:
//
// datatypes: string slice of datatypes to include in filtered XML.
func (a *aggregator) filterAggregatorByDatatype(datatypes []string) {
var newSampleGroup []sampleGroup
for _, group := range a.SampleGroup {
var tmpAgg []sample
for _, aggSample := range group.Sample {
if slices.Contains(datatypes, aggSample.DatatypeIDRef) {
tmpAgg = append(tmpAgg, aggSample)
}
}
if len(tmpAgg) > 0 {
// groupSample can have samples with different datatypeIDRef inside
// so new groupSample needs to be created
// containing all needed information and filtered samples only.
newGroup := sampleGroup{}
newGroup.SampleID = group.SampleID
newGroup.Sample = tmpAgg
newSampleGroup = append(newSampleGroup, newGroup)
}
}
a.SampleGroup = newSampleGroup
}
// filterAggregatorBySampleName filters Aggregator XML by provided sample names.
//
// Every sample has a name specified in the XML.
// This function filters the samples based on their names.
// The match can be exact or can be based on regex match.
//
// Parameters:
//
// sampleNames: string slice of sample names to include in filtered XML.
func (a *aggregator) filterAggregatorBySampleName(sampleNames []string) {
var newSampleGroup []sampleGroup
for _, group := range a.SampleGroup {
var tmpAgg []sample
for _, aggSample := range group.Sample {
if shouldAddSample(aggSample, sampleNames) {
tmpAgg = append(tmpAgg, aggSample)
}
}
if len(tmpAgg) > 0 {
newGroup := sampleGroup{}
newGroup.SampleID = group.SampleID
newGroup.Sample = tmpAgg
newSampleGroup = append(newSampleGroup, newGroup)
}
}
a.SampleGroup = newSampleGroup
}
// shouldAddSample is a helper function for filterAggregatorBySampleName
// that checks if the sample should be added to the sample group.
func shouldAddSample(s sample, sampleNames []string) bool {
matches := metricPatternRegex.FindStringSubmatch(s.SampleName)
for _, v := range sampleNames {
if s.SampleName == v {
return true
}
if len(matches) == 4 {
if matches[3] == v {
return true
}
}
}
return false
}
// filterAggInterfaceByDatatype filter aggregator interface XML by provided datatypes.
//
// Aggregator interface XML contains many aggregator samples inside, each with datatype assigned.
// This function filters aggregator samples based on their datatype.
//
// Parameters:
//
// datatypes: string slice of datatypes to include in filtered XML.
// dtMetricsFound: a map of found datatypes for all GUIDs.
func (a *aggregatorInterface) filterAggInterfaceByDatatype(datatypes []string, dtMetricsFound map[string]bool) {
newAggSample := aggregatorSamples{}
for _, s := range a.AggregatorSamples.AggregatorSample {
if slices.Contains(datatypes, s.DatatypeIDRef) {
dtMetricsFound[s.DatatypeIDRef] = true
newAggSample.AggregatorSample = append(newAggSample.AggregatorSample, s)
}
}
a.AggregatorSamples = newAggSample
}
// filterAggInterfaceBySampleName filters aggregator interface XML by sample names.
//
// This function filters aggregator samples based on the provided sampleNames.
// When the name for the sample is unique the match is exact.
// When the name is per resource (i.e. Cx_) the match is regex based.
//
// Parameters:
//
// sampleNames: string slice of sample names to include in filtered XML.
// sMetricsFound: a map of found metric names for all GUIDs.
func (a *aggregatorInterface) filterAggInterfaceBySampleName(sampleNames []string, sMetricsFound map[string]bool) {
newAggSample := aggregatorSamples{}
for _, s := range a.AggregatorSamples.AggregatorSample {
if shouldAddAggregatorSample(s, sampleNames, sMetricsFound) {
newAggSample.AggregatorSample = append(newAggSample.AggregatorSample, s)
}
}
a.AggregatorSamples = newAggSample
}
// shouldAddAggregatorSample is a helper function for filterAggInterfaceBySampleName
// that checks if if the sample should be added to the aggregator samples.
func shouldAddAggregatorSample(s aggregatorSample, sampleNames []string, sMetricsFound map[string]bool) bool {
matches := metricPatternRegex.FindStringSubmatch(s.SampleName)
for _, userMetricInput := range sampleNames {
if s.SampleName == userMetricInput {
sMetricsFound[userMetricInput] = true
return true
}
if len(matches) == 4 {
if matches[3] == userMetricInput {
sMetricsFound[userMetricInput] = true
return true
}
}
}
return false
}