-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathalgorithm.go
More file actions
162 lines (140 loc) · 4.18 KB
/
Copy pathalgorithm.go
File metadata and controls
162 lines (140 loc) · 4.18 KB
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
package orca
import (
"crypto/md5"
"fmt"
"regexp"
"time"
contract "github.com/orca-telemetry/contract/go"
)
// naming convention
var algorithmNamePattern = regexp.MustCompile(`^[A-Z][a-zA-Z0-9]*$`)
// RemoteAlgorithm represents an algorithm from another processor
type RemoteAlgorithm struct {
ProcessorName string
ProcessorRuntime string
Name string
Version string
}
// FullName returns the full name of the remote algorithm
func (r RemoteAlgorithm) FullName() string {
return fmt.Sprintf("%s_%s", r.Name, r.Version)
}
// AlgorithmFunc is the signature for the function that is executed
// when an algorithm is run
type AlgorithmFunc func(params *ExecutionParams) (Result, error)
// Algorithm represents a registered algorithm
type Algorithm struct {
Name string
Version string
Description string
WindowType *WindowType
ExecFunc AlgorithmFunc
ResultType contract.ResultType
Dependencies []Dependency
SelfLookbackN int
SelfLookbackTd time.Duration
SelfLookbackGapN int
SelfLookbackGapTd time.Duration
}
// FullName returns the name of the algorithm as "<name>_<version>"
func (a Algorithm) FullName() string {
return fmt.Sprintf("%s_%s", a.Name, a.Version)
}
// ID returns the globally unique identifier
func (a Algorithm) ID(processor string, runtime string) string {
hash := md5.Sum([]byte(runtime))
return fmt.Sprintf("%s_%s_%x", a.Name, a.Version, hash)
}
// AlgorithmOptions define a set of options for configuring
// the AddAlgorithm call
type AlgorithmOptions struct {
DependsOn []Dependency
SelfLookbackN int
SelfLookbackTd time.Duration
SelfLookbackGapN int
SelfLookbackGapTd time.Duration
}
type AlgorithmOption func(*AlgorithmOptions)
type Dependency struct {
Algorithm *Algorithm
Lookback LookbackOption
}
// WithDependencies registers a set of dependencies
func WithDependencies(dependencies []Dependency) AlgorithmOption {
return func(o *AlgorithmOptions) {
o.DependsOn = dependencies
}
}
// WithLookbackN sets the number-based lookback
func WithSelfLookbackN(n int) AlgorithmOption {
return func(o *AlgorithmOptions) {
o.SelfLookbackN = n
}
}
// WithLookbackTD sets the time-based lookback
func WithSelfLookbackTD(td time.Duration) AlgorithmOption {
return func(o *AlgorithmOptions) {
o.SelfLookbackTd = td
}
}
func WithSelfLookbackGapN(n int) AlgorithmOption {
return func(o *AlgorithmOptions) {
o.SelfLookbackGapN = n
}
}
func WithSelfLookbackGapTD(td time.Duration) AlgorithmOption {
return func(o *AlgorithmOptions) {
o.SelfLookbackGapTd = td
}
}
// NewAlgorithm creates a new instance of an algorithm, enforcing
// certain checks
//
// Should be used to create a new algorithm
func NewAlgorithm(
name string,
version string,
description string,
windowType *WindowType,
execFunc AlgorithmFunc,
resultKind ResultKind,
options ...AlgorithmOption,
) (*Algorithm, error) {
if !algorithmNamePattern.MatchString(name) {
return nil, InvalidAlgorithmArgumentError{fmt.Sprintf("algorithm name '%s' must be in PascalCase", name)}
}
if !semverPattern.MatchString(version) {
return nil, InvalidAlgorithmArgumentError{fmt.Sprintf("version '%s' must follow basic semantic versioning", version)}
}
opts := &AlgorithmOptions{}
for _, option := range options {
option(opts)
}
var resultTypeContract contract.ResultType
switch resultKind {
case KindStruct:
resultTypeContract = contract.ResultType_STRUCT
case KindArray:
resultTypeContract = contract.ResultType_ARRAY
case KindValue:
resultTypeContract = contract.ResultType_VALUE
case KindNone:
resultTypeContract = contract.ResultType_NONE
default:
return nil, InvalidAlgorithmReturnTypeError{fmt.Sprintf("result type not supported. found: %v", resultKind)}
}
algo := &Algorithm{
Name: name,
Version: version,
Description: description,
WindowType: windowType,
ExecFunc: execFunc,
ResultType: resultTypeContract,
Dependencies: opts.DependsOn,
SelfLookbackN: opts.SelfLookbackN,
SelfLookbackTd: opts.SelfLookbackTd,
SelfLookbackGapN: opts.SelfLookbackGapN,
SelfLookbackGapTd: opts.SelfLookbackGapTd,
}
return algo, nil
}