-
Notifications
You must be signed in to change notification settings - Fork 3
/
reader.go
138 lines (127 loc) · 4.68 KB
/
reader.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
package configuration
import (
"encoding/json"
"fmt"
"io/ioutil"
"recommender/backoff"
"recommender/schematree"
"recommender/strategy"
"github.com/pkg/errors"
)
//Layer defines configuration of one layer (condition, backoff pair) in the workflow
type Layer struct {
Condition string // executed condition aboveThreshold, tooManyRecommendations,tooFewRecommendations
Backoff string // executed backoff splitProperty, deleteLowFrequency
Threshold int // neeeded for conditions
ThresholdFloat float32 // needed for condition TooUnlikelyRecommendationsCondition
Merger string // needed for splitintosubsets backoff; max, avg
Splitter string // needed for splitintosubsets backoff everySecondItem, twoSupportRanges
Stepsize string // needed for deletelowfrequentitmes backoff stepsizeLinear, stepsizeProportional
ParallelExecutions int // needed for deletelowfrequentitmes backoff
}
//Configuration defines one workflow configuration
type Configuration struct {
Testset string // testset to apply (only relevant for batch evaluation. Inrelevant for standard usage)
Layers []Layer // layers to apply
}
//ReadConfigFile reads json config file <name> to Configuration struct
func ReadConfigFile(name *string) (conf *Configuration, err error) {
var c Configuration
file, err := ioutil.ReadFile(*name)
if err != nil {
err = errors.Errorf("Read File failed")
return
}
err = json.Unmarshal(file, &c)
conf = &c
return
}
//ConfigToWorkflow converts a configuration to a workflow
func ConfigToWorkflow(config *Configuration, tree *schematree.SchemaTree) (wf *strategy.Workflow, err error) {
workflow := strategy.Workflow{}
for i, l := range config.Layers {
var cond strategy.Condition
var back strategy.Procedure
//switch the conditions
switch l.Condition {
case "aboveThreshold":
cond = strategy.MakeAboveThresholdCondition(l.Threshold)
case "tooUnlikelyRecommendationsCondition":
cond = strategy.MakeTooUnlikelyRecommendationsCondition(l.ThresholdFloat)
case "tooFewRecommendations":
cond = strategy.MakeTooFewRecommendationsCondition(l.Threshold)
case "always":
cond = strategy.MakeAlwaysCondition()
default:
cond = strategy.MakeAlwaysCondition()
err = errors.Errorf("Condition not found: " + l.Condition)
}
//switch the backoffs
switch l.Backoff {
case "deleteLowFrequency":
switch l.Stepsize {
case "stepsizeLinear":
back = strategy.MakeDeleteLowFrequencyProcedure(tree, l.ParallelExecutions, backoff.StepsizeLinear, backoff.MakeMoreThanInternalCondition(l.Threshold))
case "stepsizeProportional":
back = strategy.MakeDeleteLowFrequencyProcedure(tree, l.ParallelExecutions, backoff.StepsizeProportional, backoff.MakeMoreThanInternalCondition(l.Threshold))
default:
err = errors.Errorf("Merger not found")
return
}
case "standard":
back = strategy.MakeAssessmentAwareDirectProcedure()
case "splitProperty":
var merger backoff.MergerFunc
var splitter backoff.SplitterFunc
switch l.Merger {
case "max":
merger = backoff.MaxMerger
case "avg":
merger = backoff.AvgMerger
default:
err = errors.Errorf("Merger not found")
return
}
switch l.Splitter {
case "everySecondItem":
splitter = backoff.EverySecondItemSplitter
case "twoSupportRanges":
splitter = backoff.TwoSupportRangesSplitter
default:
err = errors.Errorf("Splitter not found")
return
}
back = strategy.MakeSplitPropertyProcedure(tree, splitter, merger)
case "tooFewRecommendations":
cond = strategy.MakeTooFewRecommendationsCondition(l.Threshold)
default:
cond = strategy.MakeAlwaysCondition()
err = errors.Errorf("Backoff not found: " + l.Backoff)
}
//create the wf layer
workflow.Push(cond, back, fmt.Sprintf("layer %v", i))
}
wf = &workflow
return
}
// Test if the configuration is well formatted and all attributes for the chosen strategy are set.
// Check for correct attribution happens in configToWorkflow()
func (conf *Configuration) Test() (err error) {
if len(conf.Layers) == 0 {
err = errors.Errorf("Configuration File Failure: No Layers Specified")
return
}
for i, lay := range conf.Layers {
if lay.Backoff == "" {
err = errors.Errorf("Configuration File Failure: Layer %v Backoff Strategy is empty", i)
return
}
if lay.Backoff == "splitProperty" && (lay.Merger == "" || lay.Splitter == "") {
err = errors.Errorf("Configuration File Failure: Layer %v needs splitter and merger", i)
}
if lay.Backoff == "deleteLowFrequency" && (lay.Stepsize == "" || lay.ParallelExecutions == 0) {
err = errors.Errorf("Configuration File Failure: Layer %v needs Stepsize Function and #parallel executions", i)
}
}
return nil
}