-
Notifications
You must be signed in to change notification settings - Fork 24
/
arithmetic-combinator.go
104 lines (88 loc) · 3.27 KB
/
arithmetic-combinator.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
package components
import (
"errors"
"go.uber.org/fx"
policylangv1 "github.com/fluxninja/aperture/api/gen/proto/go/aperture/policy/language/v1"
"github.com/fluxninja/aperture/pkg/config"
"github.com/fluxninja/aperture/pkg/notifiers"
"github.com/fluxninja/aperture/pkg/policies/controlplane/iface"
"github.com/fluxninja/aperture/pkg/policies/controlplane/runtime"
)
// ArithmeticOperator is the type of arithmetic operation.
type ArithmeticOperator int8
//go:generate enumer -type=ArithmeticOperator -output=arithmetic-operator-string.go
const (
UnknownArithmetic ArithmeticOperator = iota
Add
Sub
Mul
Div
Xor
LShift
RShift
)
// ArithmeticCombinator takes lhs, rhs input signals and emits computed output via arithmetic operation.
type ArithmeticCombinator struct {
// The arithmetic operation can be addition, subtraction, multiplication, division, XOR, left bit shift or right bit shift.
operator ArithmeticOperator
}
// Name implements runtime.Component.
func (*ArithmeticCombinator) Name() string { return "ArithmeticCombinator" }
// Type implements runtime.Component.
func (*ArithmeticCombinator) Type() runtime.ComponentType {
return runtime.ComponentTypeSignalProcessor
}
// ShortDescription implements runtime.Component.
func (arith *ArithmeticCombinator) ShortDescription() string { return arith.operator.String() }
// Make sure ArithmeticCombinator complies with Component interface.
var _ runtime.Component = (*ArithmeticCombinator)(nil)
// NewArithmeticCombinatorAndOptions returns a new ArithmeticCombinator and its Fx options.
func NewArithmeticCombinatorAndOptions(arithmeticCombinatorProto *policylangv1.ArithmeticCombinator, _ string, _ iface.Policy) (runtime.Component, fx.Option, error) {
operator, err := ArithmeticOperatorString(arithmeticCombinatorProto.Operator)
if err != nil {
return nil, fx.Options(), err
}
if operator == UnknownArithmetic {
return nil, fx.Options(), errors.New("unknown arithmetic operator")
}
arith := ArithmeticCombinator{
operator: operator,
}
return &arith, fx.Options(), nil
}
// Execute implements runtime.Component.Execute.
func (arith *ArithmeticCombinator) Execute(inPortReadings runtime.PortToReading, tickInfo runtime.TickInfo) (runtime.PortToReading, error) {
lhs := inPortReadings.ReadSingleReadingPort("lhs")
rhs := inPortReadings.ReadSingleReadingPort("rhs")
output := runtime.InvalidReading()
var err error
if lhs.Valid() && rhs.Valid() {
lhsVal, rhsVal := lhs.Value(), rhs.Value()
switch arith.operator {
case Add:
output = runtime.NewReading(lhsVal + rhsVal)
case Sub:
output = runtime.NewReading(lhsVal - rhsVal)
case Mul:
output = runtime.NewReading(lhsVal * rhsVal)
case Div:
if rhsVal == 0 {
output = runtime.InvalidReading()
} else {
output = runtime.NewReading(lhsVal / rhsVal)
}
case Xor:
output = runtime.NewReading(float64(int(lhsVal) ^ int(rhsVal)))
case LShift:
output = runtime.NewReading(float64(int(lhsVal) << int(rhsVal)))
case RShift:
output = runtime.NewReading(float64(int(lhsVal) >> int(rhsVal)))
}
}
return runtime.PortToReading{
"output": []runtime.Reading{output},
}, err
}
// DynamicConfigUpdate is a no-op for ArithmeticCombinator.
func (arith *ArithmeticCombinator) DynamicConfigUpdate(event notifiers.Event, unmarshaller config.Unmarshaller) {
}