-
Notifications
You must be signed in to change notification settings - Fork 3
/
pick_samples.go
136 lines (129 loc) · 4 KB
/
pick_samples.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
package steps
import (
"fmt"
"log"
"strconv"
"github.com/bitflow-stream/go-bitflow/bitflow"
"github.com/bitflow-stream/go-bitflow/script/reg"
)
func RegisterPickPercent(b reg.ProcessorRegistry) {
b.RegisterStep("pick",
func(p *bitflow.SamplePipeline, params map[string]interface{}) error {
counter := float64(0)
pick_percentage := params["percent"].(float64)
p.Add(&SampleFilter{
Description: bitflow.String(fmt.Sprintf("Pick %.2f%%", pick_percentage*100)),
IncludeFilter: func(_ *bitflow.Sample, _ *bitflow.Header) (bool, error) {
counter += pick_percentage
if counter > 1.0 {
counter -= 1.0
return true, nil
}
return false, nil
},
})
return nil
},
"Forward only a percentage of samples, parameter is in the range 0..1").
Required("percent", reg.Float())
}
func RegisterPickHead(b reg.ProcessorRegistry) {
b.RegisterStep("head",
func(p *bitflow.SamplePipeline, params map[string]interface{}) (err error) {
doClose := params["close"].(bool)
num := params["num"].(int)
if err == nil {
processed := 0
proc := &bitflow.SimpleProcessor{
Description: "Pick first " + strconv.Itoa(num) + " samples",
}
proc.Process = func(sample *bitflow.Sample, header *bitflow.Header) (*bitflow.Sample, *bitflow.Header, error) {
if num > processed {
processed++
return sample, header, nil
} else {
if doClose {
proc.Error(nil) // Stop processing without an error
}
return nil, nil, nil
}
}
p.Add(proc)
}
return
},
"Forward only a number of the first processed samples. The whole pipeline is closed afterwards, unless close=false is given.").
Required("num", reg.Int()).
Optional("close", reg.Bool(), false)
}
func RegisterSkipHead(b reg.ProcessorRegistry) {
b.RegisterStep("skip",
func(p *bitflow.SamplePipeline, params map[string]interface{}) (err error) {
num := params["num"].(int)
if err == nil {
dropped := 0
p.Add(&bitflow.SimpleProcessor{
Description: "Drop first " + strconv.Itoa(num) + " samples",
Process: func(sample *bitflow.Sample, header *bitflow.Header) (*bitflow.Sample, *bitflow.Header, error) {
if dropped >= num {
return sample, header, nil
} else {
dropped++
return nil, nil, nil
}
},
})
}
return
},
"Drop a number of samples in the beginning").
Required("num", reg.Int())
}
func RegisterPickTail(b reg.ProcessorRegistry) {
b.RegisterStep("tail",
func(p *bitflow.SamplePipeline, params map[string]interface{}) (err error) {
num := params["num"].(int)
if err == nil {
ring := bitflow.NewSampleRing(num)
proc := &bitflow.SimpleProcessor{
Description: "Read until end of stream, and forward only the last " + strconv.Itoa(num) + " samples",
Process: func(sample *bitflow.Sample, header *bitflow.Header) (*bitflow.Sample, *bitflow.Header, error) {
ring.Push(sample, header)
return nil, nil, nil
},
}
proc.OnClose = func() {
flush := ring.Get()
log.Printf("%v: Reached end of stream, now flushing %v samples", proc, len(flush))
for _, sample := range flush {
if err := proc.NoopProcessor.Sample(sample.Sample, sample.Header); err != nil {
proc.Error(err)
break
}
}
}
p.Add(proc)
}
return
},
"Forward only a number of the first processed samples. The whole pipeline is closed afterwards, unless close=false is given.").
Required("num", reg.Int())
}
func RegisterDropInvalid(b reg.ProcessorRegistry) {
b.RegisterStep("drop-invalid",
func(p *bitflow.SamplePipeline, params map[string]interface{}) error {
p.Add(&SampleFilter{
Description: bitflow.String("Drop samples with invalid values (NaN/Inf)"),
IncludeFilter: func(s *bitflow.Sample, _ *bitflow.Header) (bool, error) {
for _, val := range s.Values {
if !IsValidNumber(float64(val)) {
return false, nil
}
}
return true, nil
},
})
return nil
},
"Drop samples that contain NaN or Inf values.")
}