-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfgbase.go
238 lines (197 loc) · 5.5 KB
/
fgbase.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
// Package fgbase layers a ready-send flow mechanism on top of goroutines.
// https://github.com/vectaport/fgbase/wiki
package fgbase
import (
"flag"
"log"
"os"
"runtime"
"strconv"
"time"
)
func check(e error) {
if e != nil {
StderrLog.Printf("ERROR: %v\n", e)
os.Exit(1)
}
}
// Log for tracing flowgraph execution.
var StdoutLog = log.New(os.Stdout, "", 0)
// Log for collecting error messages.
var StderrLog = log.New(os.Stderr, "", 0)
// GlobalStats will enable global flowgraph stats for uncommon debug-purposes.
// Otherwise it should be left false because it requires a global mutex.
var GlobalStats = false
// Trace level constants.
type TraceLevelType int
const (
QQ TraceLevelType = iota // ultra-quiet for minimal stats
Q // quiet, default
V // trace Node execution
VV // trace channel IO
VVV // trace state before select
VVVV // full-length array dumps
)
// Map from string to enum for trace flag checking.
var TraceLevels = map[string]TraceLevelType{
"QQ": QQ,
"Q": Q,
"V": V,
"VV": VV,
"VVV": VVV,
"VVVV": VVVV,
}
// String method for TraceLevelType
func (t TraceLevelType) String() string {
return []string{
"QQ",
"Q",
"V",
"VV",
"VVV",
"VVVV",
}[t]
}
// End of flow
type Error string
func (e Error) Error() string {
return string(e)
}
const EOF = Error("EOF")
// IsEOF returns true if interface{} is EOF error
func IsEOF(v interface{}) (eof bool) {
return v == EOF
/*
if err, ok := v.(error)
if ok {
eof = err.Error() == EOF
}
return
*/
}
const (
Old int = iota
New
)
// TraceStyle is Old or New
var TraceStyle = Old
// TraceLevel enables tracing, writes to StdoutLog if TraceLevel>Q.
var TraceLevel = Q
// TraceIndent is trace by Node id tabs.
var TraceIndent = false
// TraceFireCnt is the number of node executions.
var TraceFireCnt = true
// TraceSeconds that have elapsed.
var TraceSeconds = false
// TraceTypes in full detail, including common types.
var TraceTypes = false
// TracePorts by name using dot notation
var TracePorts = false
// Trace Node pointer.
var TracePointer = false
// DotOutput is Graphviz .dot output
var DotOutput = false
// GMLOutput is gml output
var GmlOutput = false
// NodeID is a unique node id.
var NodeID int64
// EgdeID is a unique edge id.
var EdgeID int64
// RunTime is the duration to run this flowgraph.
var RunTime time.Duration = -1
// Buffer size for every channel.
var ChannelSize = 1
// globalFireCnt is the global count of Node executions
var globalFireCnt int64
// summarizing is true when summary is being generated
var summarizing = false
// wrapper adds channel to steer ack
type ackWrap struct {
node *Node
datum interface{}
ack2 chan struct{}
}
// MakeGraph returns a slice of Edge and a slice of Node.
func MakeGraph(sze, szn int) ([]Edge, []Node) {
return MakeEdges(sze), MakeNodes(szn)
}
// ConfigByFlag initializes a standard set of command line arguments for flowgraph utilities,
// while at the same time parsing all other flags. Use the defaults argument to override
// default settings for ncore, chanz, sec, trace, trsec, trtyp, trport, summ, dot, and gml.
// Use -help to see the standard set.
func ConfigByFlag(defaults map[string]interface{}) {
var ncoreDef interface{} = runtime.NumCPU() - 1
var secDef interface{} = 1
var traceDef interface{} = "V"
var chanszDef interface{} = 1
var trsecDef interface{} = false
var trtypDef interface{} = false
var trportDef interface{} = false
var dotDef interface{} = false
var gmlDef interface{} = false
if defaults != nil {
if defaults["ncore"] != nil {
ncoreDef = defaults["ncore"]
}
if defaults["sec"] != nil {
secDef = defaults["sec"]
}
if defaults["trace"] != nil {
traceDef = defaults["trace"]
}
if defaults["chansz"] != nil {
chanszDef = defaults["chansz"]
}
if defaults["trsec"] != nil {
trsecDef = defaults["trsec"]
}
if defaults["trtyp"] != nil {
trtypDef = defaults["trtyp"]
}
if defaults["trport"] != nil {
trportDef = defaults["trport"]
}
if defaults["dot"] != nil {
dotDef = defaults["dot"]
}
if defaults["gml"] != nil {
gmlDef = defaults["gml"]
}
}
ncorePtr := flag.Int("ncore", ncoreDef.(int), "# cores to use, max "+strconv.Itoa(runtime.NumCPU()))
secPtr := flag.Int("sec", secDef.(int), "seconds to run")
tracePtr := flag.String("trace", traceDef.(string), "trace level, QQ|Q|V|VV|VVV|VVVV")
chanszPtr := flag.Int("chansz", chanszDef.(int), "channel size")
trsecPtr := flag.Bool("trsec", trsecDef.(bool), "trace seconds")
trtypPtr := flag.Bool("trtyp", trtypDef.(bool), "trace types")
trportPtr := flag.Bool("trport", trportDef.(bool), "trace ports")
dotPtr := flag.Bool("dot", dotDef.(bool), "graphviz output")
gmlPtr := flag.Bool("gml", gmlDef.(bool), "GML output")
flag.Parse()
runtime.GOMAXPROCS(*ncorePtr)
RunTime = time.Duration(*secPtr) * time.Second
TraceLevel = TraceLevels[*tracePtr]
ChannelSize = *chanszPtr
TraceSeconds = *trsecPtr
TraceTypes = *trtypPtr
TracePorts = *trportPtr
DotOutput = *dotPtr
GmlOutput = *gmlPtr
}
// When the flowgraph started running.
var StartTime time.Time
// TimeSinceStart returns time since start of running flowgraph.
func TimeSinceStart() float64 {
if IsZero(StartTime) {
return -1
}
return time.Since(StartTime).Seconds()
}
// StringsToMap converts []string into map[string]int.
func StringsToMap(strings []string) map[string]int {
m := make(map[string]int)
for i := range strings {
m[strings[i]] = i
}
return m
}