/
context.go
112 lines (93 loc) · 2.85 KB
/
context.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
package rete
import (
"container/list"
"context"
"github.com/project-flogo/rules/common/model"
)
var reteCTXKEY = model.RetecontextKeyType{}
type reteCtx interface {
getConflictResolver() conflictRes
getOpsList() *list.List
getNetwork() Network
getRuleSession() model.RuleSession
OnValueChange(tuple model.Tuple, prop string)
}
//store any context, may not know all keys upfront
type reteCtxImpl struct {
cr conflictRes
opsList *list.List
network Network
rs model.RuleSession
//in each action, this map is updated with new ones
//key is the added tuple, value is true
// (we simply want the unique set of newly added tuples)
addMap map[model.Tuple]bool
//in each action, this map is updated with modifications
//key is the added tuple, value is a map of the changed property to true
// (we simply want unique modified tuples and unique props in each that changed)
modifyMap map[model.Tuple]map[string]bool
//in each action, this map is updated with deletions
//key is the deleted tuple value is always true
// (we simply want a unique set of deleted tuples)
deleteMap map[model.Tuple]bool
}
func (rctx *reteCtxImpl) getConflictResolver() conflictRes {
return rctx.cr
}
func (rctx *reteCtxImpl) getOpsList() *list.List {
return rctx.opsList
}
func (rctx *reteCtxImpl) getNetwork() Network {
return rctx.network
}
func (rctx *reteCtxImpl) getRuleSession() model.RuleSession {
return rctx.rs
}
func (rctx *reteCtxImpl) OnValueChange(tuple model.Tuple, prop string) {
//if handle does not exist means its new
if nil != rctx.network.getHandle(tuple) {
propMap := rctx.modifyMap[tuple]
if propMap == nil {
propMap = make(map[string]bool)
propMap[prop] = true
rctx.modifyMap[tuple] = propMap
} else {
propMap[prop] = true
}
}
}
func newReteCtxImpl(network Network, rs model.RuleSession) reteCtx {
reteCtxVal := reteCtxImpl{}
reteCtxVal.cr = newConflictRes()
reteCtxVal.opsList = list.New()
reteCtxVal.network = network
reteCtxVal.rs = rs
reteCtxVal.addMap = make(map[model.Tuple]bool)
reteCtxVal.modifyMap = make(map[model.Tuple]map[string]bool)
reteCtxVal.deleteMap = make(map[model.Tuple]bool)
return &reteCtxVal
}
func getReteCtx(ctx context.Context) reteCtx {
intr := ctx.Value(reteCTXKEY)
if intr == nil {
return nil
}
return intr.(reteCtx)
}
func newReteCtx(ctx context.Context, network Network, rs model.RuleSession) (context.Context, reteCtx) {
reteCtxVar := newReteCtxImpl(network, rs)
ctx = context.WithValue(ctx, reteCTXKEY, reteCtxVar)
return ctx, reteCtxVar
}
func getOrSetReteCtx(ctx context.Context, network Network, rs model.RuleSession) (reteCtx, bool, context.Context) {
isRecursive := false
newCtx := ctx
reteCtxVar := getReteCtx(ctx)
if reteCtxVar == nil {
newCtx, reteCtxVar = newReteCtx(ctx, network, rs)
isRecursive = false
} else {
isRecursive = true
}
return reteCtxVar, isRecursive, newCtx
}