-
Notifications
You must be signed in to change notification settings - Fork 6
/
facts.go
69 lines (56 loc) · 1.48 KB
/
facts.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
package scientist
import (
"math/rand"
"time"
)
// Facts holds behavior information for an experiment.
type Facts struct {
behaviors map[string]Behavior
behaviorsAccess []string
}
// NewFacts create a new set of facts for a experiment.
func NewFacts() *Facts {
return &Facts{
behaviors: make(map[string]Behavior),
}
}
// Name returns the facts name as `experiment`.
func (f *Facts) Name() string {
return "experiment"
}
// Control returns the control behavior.
func (f *Facts) Control() Behavior {
return f.behaviors["__control__"]
}
// Behavior returns a candidate behavior by its name.
func (f *Facts) Behavior(name string) Behavior {
return f.behaviors[name]
}
// Use sets the control behavior.
func (f *Facts) Use(behavior Behavior) error {
return f.tryBehavior("__control__", behavior)
}
// Try adds a new candidate behavior.
// The name of each candidate must be unique.
func (f *Facts) Try(name string, behavior Behavior) error {
return f.tryBehavior(name, behavior)
}
// Shuffle randomizes the behavior access.
func (f *Facts) Shuffle() []string {
t := time.Now()
rand.Seed(int64(t.Nanosecond()))
arr := f.behaviorsAccess
for i := len(arr) - 1; i > 0; i-- {
j := rand.Intn(i)
arr[i], arr[j] = arr[j], arr[i]
}
return arr
}
func (f *Facts) tryBehavior(name string, behavior Behavior) error {
if _, exist := f.behaviors[name]; exist {
return behaviorAlreadyExist{name}
}
f.behaviors[name] = behavior
f.behaviorsAccess = append(f.behaviorsAccess, name)
return nil
}