Skip to content

Commit 2fa91c8

Browse files
authored
Merge pull request #85 from qmuntal/optg
Reduce ToGraph memory usage
2 parents 30a7b0c + 3ee7ce7 commit 2fa91c8

File tree

2 files changed

+22
-22
lines changed

2 files changed

+22
-22
lines changed

graph.go

+14-22
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,20 @@ func (g *graph) formatStateMachine(sm *StateMachine) string {
2626

2727
for _, sr := range stateList {
2828
if sr.Superstate == nil {
29-
sb.WriteString(g.formatOneState(sr, 1))
29+
g.formatOneState(&sb, sr, 1)
3030
}
3131
}
3232
for _, sr := range stateList {
3333
if sr.HasInitialState {
3434
dest := sm.stateConfig[sr.InitialTransitionTarget]
3535
if dest != nil {
3636
src := clusterStr(sr.State, true, true)
37-
sb.WriteString(g.formatOneLine(src, str(dest.State, true), ""))
37+
formatOneLine(&sb, src, str(dest.State, true), "")
3838
}
3939
}
4040
}
4141
for _, sr := range stateList {
42-
sb.WriteString(g.formatAllStateTransitions(sm, sr))
42+
g.formatAllStateTransitions(&sb, sm, sr)
4343
}
4444
initialState, err := sm.State(context.Background())
4545
if err == nil {
@@ -69,12 +69,11 @@ func (g *graph) formatActions(sr *stateRepresentation) string {
6969
return strings.Join(es, "\\n")
7070
}
7171

72-
func (g *graph) formatOneState(sr *stateRepresentation, level int) string {
72+
func (g *graph) formatOneState(sb *strings.Builder, sr *stateRepresentation, level int) {
7373
var indent string
7474
for i := 0; i < level; i++ {
7575
indent += "\t"
7676
}
77-
var sb strings.Builder
7877
sb.WriteString(fmt.Sprintf("%s%s [label=\"%s", indent, str(sr.State, true), str(sr.State, false)))
7978
act := g.formatActions(sr)
8079
if act != "" {
@@ -93,11 +92,10 @@ func (g *graph) formatOneState(sr *stateRepresentation, level int) string {
9392
sb.WriteString(fmt.Sprintf("%s\t\"%s\" [label=\"\", shape=point];\n", indent, clusterStr(sr.State, false, true)))
9493
}
9594
for _, substate := range sr.Substates {
96-
sb.WriteString(g.formatOneState(substate, level+1))
95+
g.formatOneState(sb, substate, level+1)
9796
}
9897
sb.WriteString(indent + "}\n")
9998
}
100-
return sb.String()
10199
}
102100

103101
func (g *graph) getEntryActions(ab []actionBehaviour, t Trigger) []string {
@@ -110,9 +108,7 @@ func (g *graph) getEntryActions(ab []actionBehaviour, t Trigger) []string {
110108
return actions
111109
}
112110

113-
func (g *graph) formatAllStateTransitions(sm *StateMachine, sr *stateRepresentation) string {
114-
var sb strings.Builder
115-
111+
func (g *graph) formatAllStateTransitions(sb *strings.Builder, sm *StateMachine, sr *stateRepresentation) {
116112
triggerList := make([]triggerBehaviour, 0, len(sr.TriggerBehaviours))
117113
for _, triggers := range sr.TriggerBehaviours {
118114
triggerList = append(triggerList, triggers...)
@@ -137,25 +133,25 @@ func (g *graph) formatAllStateTransitions(sm *StateMachine, sr *stateRepresentat
137133
if _, ok := lines[ln]; !ok {
138134
order = append(order, ln)
139135
}
140-
lines[ln] = append(lines[ln], g.formatOneTransition(t.Trigger, nil, t.Guard))
136+
lines[ln] = append(lines[ln], formatOneTransition(t.Trigger, nil, t.Guard))
141137
case *reentryTriggerBehaviour:
142138
actions := g.getEntryActions(sr.EntryActions, t.Trigger)
143139
ln := line{sr.State, t.Destination}
144140
if _, ok := lines[ln]; !ok {
145141
order = append(order, ln)
146142
}
147-
lines[ln] = append(lines[ln], g.formatOneTransition(t.Trigger, actions, t.Guard))
143+
lines[ln] = append(lines[ln], formatOneTransition(t.Trigger, actions, t.Guard))
148144
case *internalTriggerBehaviour:
149145
actions := g.getEntryActions(sr.EntryActions, t.Trigger)
150146
ln := line{sr.State, sr.State}
151147
if _, ok := lines[ln]; !ok {
152148
order = append(order, ln)
153149
}
154-
lines[ln] = append(lines[ln], g.formatOneTransition(t.Trigger, actions, t.Guard))
150+
lines[ln] = append(lines[ln], formatOneTransition(t.Trigger, actions, t.Guard))
155151
case *transitioningTriggerBehaviour:
156152
src := sm.stateConfig[sr.State]
157153
if src == nil {
158-
return ""
154+
continue
159155
}
160156
dest := sm.stateConfig[t.Destination]
161157
var actions []string
@@ -172,21 +168,19 @@ func (g *graph) formatAllStateTransitions(sm *StateMachine, sr *stateRepresentat
172168
if _, ok := lines[ln]; !ok {
173169
order = append(order, ln)
174170
}
175-
lines[ln] = append(lines[ln], g.formatOneTransition(t.Trigger, actions, t.Guard))
171+
lines[ln] = append(lines[ln], formatOneTransition(t.Trigger, actions, t.Guard))
176172
case *dynamicTriggerBehaviour:
177173
// TODO: not supported yet
178174
}
179175
}
180176

181177
for _, ln := range order {
182178
content := lines[ln]
183-
sb.WriteString(g.formatOneLine(str(ln.source, true), str(ln.destination, true), strings.Join(content, "\\n")))
179+
formatOneLine(sb, str(ln.source, true), str(ln.destination, true), strings.Join(content, "\\n"))
184180
}
185-
186-
return sb.String()
187181
}
188182

189-
func (g *graph) formatOneTransition(trigger Trigger, actions []string, guards transitionGuard) string {
183+
func formatOneTransition(trigger Trigger, actions []string, guards transitionGuard) string {
190184
var sb strings.Builder
191185
sb.WriteString(str(trigger, false))
192186
if len(actions) > 0 {
@@ -202,11 +196,9 @@ func (g *graph) formatOneTransition(trigger Trigger, actions []string, guards tr
202196
return sb.String()
203197
}
204198

205-
func (g *graph) formatOneLine(fromNodeName, toNodeName, label string) string {
206-
var sb strings.Builder
199+
func formatOneLine(sb *strings.Builder, fromNodeName, toNodeName, label string) {
207200
sb.WriteString(fmt.Sprintf("\t%s -> %s [label=\"%s\"", fromNodeName, toNodeName, label))
208201
sb.WriteString("];\n")
209-
return sb.String()
210202
}
211203

212204
func clusterStr(state any, quote, init bool) string {

graph_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,11 @@ func TestStateMachine_ToGraph(t *testing.T) {
155155
})
156156
}
157157
}
158+
159+
func BenchmarkToGraph(b *testing.B) {
160+
sm := phoneCall()
161+
b.ResetTimer()
162+
for i := 0; i < b.N; i++ {
163+
_ = sm.ToGraph()
164+
}
165+
}

0 commit comments

Comments
 (0)