Browse Source

调整代码结构

gitlink
Sydonian 1 year ago
parent
commit
9ecc302416
12 changed files with 958 additions and 1199 deletions
  1. +74
    -0
      common/pkgs/ioswitch/dag/graph.go
  2. +68
    -0
      common/pkgs/ioswitch/dag/node.go
  3. +112
    -0
      common/pkgs/ioswitch/dag/var.go
  4. +8
    -0
      common/pkgs/ioswitch/exec/exec.go
  5. +1
    -1
      common/pkgs/ioswitch/exec/executor.go
  6. +1
    -1
      common/pkgs/ioswitch/exec/plan_builder.go
  7. +1
    -1
      common/pkgs/ioswitch/exec/utils.go
  8. +6
    -6
      common/pkgs/ioswitch/ops/grpc.go
  9. +0
    -446
      common/pkgs/ioswitch/plans/agent.go
  10. +10
    -20
      common/pkgs/ioswitch/plans/fromto.go
  11. +338
    -205
      common/pkgs/ioswitch/plans/ops.go
  12. +339
    -519
      common/pkgs/ioswitch/plans/parser.go

+ 74
- 0
common/pkgs/ioswitch/dag/graph.go View File

@@ -0,0 +1,74 @@
package dag

import (
"gitlink.org.cn/cloudream/common/utils/lo2"
)

type Graph[NP any, VP any] struct {
Nodes []*Node[NP, VP]
isWalking bool
nextVarID int
}

func NewGraph[NP any, VP any]() *Graph[NP, VP] {
return &Graph[NP, VP]{}
}

func (g *Graph[NP, VP]) NewNode(typ NodeType[NP, VP], props NP) *Node[NP, VP] {
n := &Node[NP, VP]{
Type: typ,
Props: props,
Graph: g,
}
typ.InitNode(n)
g.Nodes = append(g.Nodes, n)
return n
}

func (g *Graph[NP, VP]) RemoveNode(node *Node[NP, VP]) {
for i, n := range g.Nodes {
if n == node {
if g.isWalking {
g.Nodes[i] = nil
} else {
g.Nodes = lo2.RemoveAt(g.Nodes, i)
}
break
}
}
}

func (g *Graph[NP, VP]) Walk(cb func(node *Node[NP, VP]) bool) {
g.isWalking = true
for i := 0; i < len(g.Nodes); i++ {
if g.Nodes[i] == nil {
continue
}

if !cb(g.Nodes[i]) {
break
}
}
g.isWalking = false

g.Nodes = lo2.RemoveAllDefault(g.Nodes)
}

func (g *Graph[NP, VP]) genVarID() int {
g.nextVarID++
return g.nextVarID
}

func NewNode[NP any, VP any, NT NodeType[NP, VP]](graph *Graph[NP, VP], typ NT, props NP) (*Node[NP, VP], NT) {
return graph.NewNode(typ, props), typ
}

func WalkOnlyType[N NodeType[NP, VP], NP any, VP any](g *Graph[NP, VP], cb func(node *Node[NP, VP], typ N) bool) {
g.Walk(func(node *Node[NP, VP]) bool {
typ, ok := node.Type.(N)
if ok {
return cb(node, typ)
}
return true
})
}

+ 68
- 0
common/pkgs/ioswitch/dag/node.go View File

@@ -0,0 +1,68 @@
package dag

import (
"fmt"

"gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch/exec"
)

type NodeType[NP any, VP any] interface {
InitNode(node *Node[NP, VP])
String(node *Node[NP, VP]) string
GenerateOp(node *Node[NP, VP], blder *exec.PlanBuilder) error
}

type NodeEnvType string

const (
EnvUnknown NodeEnvType = ""
EnvExecutor NodeEnvType = "Executor"
EnvWorker NodeEnvType = "Worker"
)

type NodeEnv struct {
Type NodeEnvType
Worker exec.Worker
}

func (e *NodeEnv) ToEnvUnknown() {
e.Type = EnvUnknown
e.Worker = nil
}

func (e *NodeEnv) ToEnvExecutor() {
e.Type = EnvExecutor
e.Worker = nil
}

func (e *NodeEnv) ToEnvWorker(worker exec.Worker) {
e.Type = EnvWorker
e.Worker = worker
}

func (e *NodeEnv) Equals(other NodeEnv) bool {
if e.Type != other.Type {
return false
}

if e.Type != EnvWorker {
return true
}

return e.Worker.Equals(other.Worker)
}

type Node[NP any, VP any] struct {
Type NodeType[NP, VP]
Env NodeEnv
Props NP
InputStreams []*StreamVar[NP, VP]
OutputStreams []*StreamVar[NP, VP]
InputValues []*ValueVar[NP, VP]
OutputValues []*ValueVar[NP, VP]
Graph *Graph[NP, VP]
}

func (n *Node[NP, VP]) String() string {
return fmt.Sprintf("%v", n.Type.String(n))
}

+ 112
- 0
common/pkgs/ioswitch/dag/var.go View File

@@ -0,0 +1,112 @@
package dag

import "gitlink.org.cn/cloudream/common/utils/lo2"

type EndPoint[NP any, VP any] struct {
Node *Node[NP, VP]
SlotIndex int // 所连接的Node的Output或Input数组的索引
}

type StreamVar[NP any, VP any] struct {
ID int
From EndPoint[NP, VP]
Toes []EndPoint[NP, VP]
Props VP
}

func (v *StreamVar[NP, VP]) To(to *Node[NP, VP], slotIdx int) int {
v.Toes = append(v.Toes, EndPoint[NP, VP]{Node: to, SlotIndex: slotIdx})
to.InputStreams[slotIdx] = v
return len(v.Toes) - 1
}

// func (v *StreamVar[NP, VP]) NotTo(toIdx int) EndPoint[NP, VP] {
// ed := v.Toes[toIdx]
// lo2.RemoveAt(v.Toes, toIdx)
// ed.Node.InputStreams[ed.SlotIndex] = nil
// return ed
// }

func (v *StreamVar[NP, VP]) NotTo(node *Node[NP, VP]) (EndPoint[NP, VP], bool) {
for i, ed := range v.Toes {
if ed.Node == node {
v.Toes = lo2.RemoveAt(v.Toes, i)
ed.Node.InputStreams[ed.SlotIndex] = nil
return ed, true
}
}

return EndPoint[NP, VP]{}, false
}

func (v *StreamVar[NP, VP]) NotToWhere(pred func(to EndPoint[NP, VP]) bool) []EndPoint[NP, VP] {
var newToes []EndPoint[NP, VP]
var rmed []EndPoint[NP, VP]
for _, ed := range v.Toes {
if pred(ed) {
ed.Node.InputStreams[ed.SlotIndex] = nil
rmed = append(rmed, ed)
} else {
newToes = append(newToes, ed)
}
}
v.Toes = newToes
return rmed
}

func (v *StreamVar[NP, VP]) NotToAll() []EndPoint[NP, VP] {
for _, ed := range v.Toes {
ed.Node.InputStreams[ed.SlotIndex] = nil
}
toes := v.Toes
v.Toes = nil
return toes
}

func NodeNewOutputStream[NP any, VP any](node *Node[NP, VP], props VP) *StreamVar[NP, VP] {
str := &StreamVar[NP, VP]{
ID: node.Graph.genVarID(),
From: EndPoint[NP, VP]{Node: node, SlotIndex: len(node.OutputStreams)},
Props: props,
}
node.OutputStreams = append(node.OutputStreams, str)
return str
}

func NodeDeclareInputStream[NP any, VP any](node *Node[NP, VP], cnt int) {
node.InputStreams = make([]*StreamVar[NP, VP], cnt)
}

type ValueVarType int

const (
StringValueVar ValueVarType = iota
SignalValueVar
)

type ValueVar[NP any, VP any] struct {
ID int
From EndPoint[NP, VP]
Toes []EndPoint[NP, VP]
Props VP
}

func (v *ValueVar[NP, VP]) To(to *Node[NP, VP], slotIdx int) int {
v.Toes = append(v.Toes, EndPoint[NP, VP]{Node: to, SlotIndex: slotIdx})
to.InputValues[slotIdx] = v
return len(v.Toes) - 1
}

func NodeNewOutputValue[NP any, VP any](node *Node[NP, VP], props VP) *ValueVar[NP, VP] {
val := &ValueVar[NP, VP]{
ID: node.Graph.genVarID(),
From: EndPoint[NP, VP]{Node: node, SlotIndex: len(node.OutputStreams)},
Props: props,
}
node.OutputValues = append(node.OutputValues, val)
return val
}

func NodeDeclareInputValue[NP any, VP any](node *Node[NP, VP], cnt int) {
node.InputValues = make([]*ValueVar[NP, VP], cnt)
}

+ 8
- 0
common/pkgs/ioswitch/exec/exec.go View File

@@ -0,0 +1,8 @@
package exec

type Worker interface {
// 获取连接到这个worker的GRPC服务的地址
GetAddress() string
// 判断两个worker是否相同
Equals(worker Worker) bool
}

common/pkgs/ioswitch/plans/executor.go → common/pkgs/ioswitch/exec/executor.go View File

@@ -1,4 +1,4 @@
package plans
package exec

import (
"context"

common/pkgs/ioswitch/plans/plan_builder.go → common/pkgs/ioswitch/exec/plan_builder.go View File

@@ -1,4 +1,4 @@
package plans
package exec

import (
"context"

common/pkgs/ioswitch/plans/utils.go → common/pkgs/ioswitch/exec/utils.go View File

@@ -1,4 +1,4 @@
package plans
package exec

import (
"github.com/google/uuid"

+ 6
- 6
common/pkgs/ioswitch/ops/grpc.go View File

@@ -45,7 +45,7 @@ func (o *SendStream) Execute(ctx context.Context, sw *ioswitch.Switch) error {

type GetStream struct {
Signal *ioswitch.SignalVar `json:"signal"`
Get *ioswitch.StreamVar `json:"get"`
Target *ioswitch.StreamVar `json:"target"`
Output *ioswitch.StreamVar `json:"output"`
Node cdssdk.Node `json:"node"`
}
@@ -57,9 +57,9 @@ func (o *GetStream) Execute(ctx context.Context, sw *ioswitch.Switch) error {
}
defer stgglb.AgentRPCPool.Release(agtCli)

logger.Debugf("getting stream %v as %v from node %v", o.Get.ID, o.Output.ID, o.Node)
logger.Debugf("getting stream %v as %v from node %v", o.Target.ID, o.Output.ID, o.Node)

str, err := agtCli.GetStream(sw.Plan().ID, o.Get.ID, o.Signal)
str, err := agtCli.GetStream(sw.Plan().ID, o.Target.ID, o.Signal)
if err != nil {
return fmt.Errorf("getting stream: %w", err)
}
@@ -105,7 +105,7 @@ func (o *SendVar) Execute(ctx context.Context, sw *ioswitch.Switch) error {

type GetVar struct {
Signal *ioswitch.SignalVar `json:"signal"`
Get ioswitch.Var `json:"get"`
Target ioswitch.Var `json:"target"`
Output ioswitch.Var `json:"output"`
Node cdssdk.Node `json:"node"`
}
@@ -117,9 +117,9 @@ func (o *GetVar) Execute(ctx context.Context, sw *ioswitch.Switch) error {
}
defer stgglb.AgentRPCPool.Release(agtCli)

logger.Debugf("getting var %v as %v from node %v", o.Get.GetID(), o.Output.GetID(), o.Node)
logger.Debugf("getting var %v as %v from node %v", o.Target.GetID(), o.Output.GetID(), o.Node)

v2, err := agtCli.GetVar(ctx, sw.Plan().ID, o.Get, o.Signal)
v2, err := agtCli.GetVar(ctx, sw.Plan().ID, o.Target, o.Signal)
if err != nil {
return fmt.Errorf("getting var: %w", err)
}


+ 0
- 446
common/pkgs/ioswitch/plans/agent.go View File

@@ -1,446 +0,0 @@
package plans

/*
func (b *AgentPlanBuilder) IPFSRead(fileHash string, opts ...ipfs.ReadOption) *AgentStreamVar {
opt := ipfs.ReadOption{
Offset: 0,
Length: -1,
}
if len(opts) > 0 {
opt = opts[0]
}

str := &AgentStreamVar{
owner: b,
v: b.blder.NewStreamVar(),
}

b.Ops = append(b.Ops, &ops.IPFSRead{
Output: str.v,
FileHash: fileHash,
Option: opt,
})

return str
}
func (b *AgentPlanBuilder) FileRead(filePath string) *AgentStreamVar {
agtStr := &AgentStreamVar{
owner: b,
v: b.blder.NewStreamVar(),
}

b.Ops = append(b.Ops, &ops.FileRead{
Output: agtStr.v,
FilePath: filePath,
})

return agtStr
}

func (b *AgentPlanBuilder) ECReconstructAny(ec cdssdk.ECRedundancy, inBlockIndexes []int, outBlockIndexes []int, streams []*AgentStreamVar) []*AgentStreamVar {
var strs []*AgentStreamVar

var inputStrVars []*ioswitch.StreamVar
for _, str := range streams {
inputStrVars = append(inputStrVars, str.v)
}

var outputStrVars []*ioswitch.StreamVar
for i := 0; i < len(outBlockIndexes); i++ {
v := b.blder.NewStreamVar()
strs = append(strs, &AgentStreamVar{
owner: b,
v: v,
})
outputStrVars = append(outputStrVars, v)
}

b.Ops = append(b.Ops, &ops.ECReconstructAny{
EC: ec,
Inputs: inputStrVars,
Outputs: outputStrVars,
InputBlockIndexes: inBlockIndexes,
OutputBlockIndexes: outBlockIndexes,
})

return strs
}

func (b *AgentPlanBuilder) ECReconstruct(ec cdssdk.ECRedundancy, inBlockIndexes []int, streams []*AgentStreamVar) []*AgentStreamVar {
var strs []*AgentStreamVar

var inputStrVars []*ioswitch.StreamVar
for _, str := range streams {
inputStrVars = append(inputStrVars, str.v)
}

var outputStrVars []*ioswitch.StreamVar
for i := 0; i < ec.K; i++ {
v := b.blder.NewStreamVar()
strs = append(strs, &AgentStreamVar{
owner: b,
v: v,
})
outputStrVars = append(outputStrVars, v)
}

b.Ops = append(b.Ops, &ops.ECReconstruct{
EC: ec,
Inputs: inputStrVars,
Outputs: outputStrVars,
InputBlockIndexes: inBlockIndexes,
})

return strs
}

// 进行galois矩阵乘法运算,ecof * inputs
func (b *AgentPlanBuilder) ECMultiply(coef [][]byte, inputs []*AgentStreamVar, chunkSize int64) []*AgentStreamVar {
outs := make([]*AgentStreamVar, len(coef))
outVars := make([]*ioswitch.StreamVar, len(coef))
for i := 0; i < len(outs); i++ {
sv := b.blder.NewStreamVar()
outs[i] = &AgentStreamVar{
owner: b,
v: sv,
}
outVars[i] = sv
}

ins := make([]*ioswitch.StreamVar, len(inputs))
for i := 0; i < len(inputs); i++ {
ins[i] = inputs[i].v
}

b.Ops = append(b.Ops, &ops.ECMultiply{
Inputs: ins,
Outputs: outVars,
Coef: coef,
ChunkSize: chunkSize,
})

return outs
}

func (b *AgentPlanBuilder) Join(length int64, streams []*AgentStreamVar) *AgentStreamVar {
agtStr := &AgentStreamVar{
owner: b,
v: b.blder.NewStreamVar(),
}

var inputStrVars []*ioswitch.StreamVar
for _, str := range streams {
inputStrVars = append(inputStrVars, str.v)
}

b.Ops = append(b.Ops, &ops.Join{
Inputs: inputStrVars,
Output: agtStr.v,
Length: length,
})

return agtStr
}

func (b *AgentPlanBuilder) ChunkedJoin(chunkSize int, streams []*AgentStreamVar) *AgentStreamVar {
agtStr := &AgentStreamVar{
owner: b,
v: b.blder.NewStreamVar(),
}

var inputStrVars []*ioswitch.StreamVar
for _, str := range streams {
inputStrVars = append(inputStrVars, str.v)
}

b.Ops = append(b.Ops, &ops.ChunkedJoin{
Inputs: inputStrVars,
Output: agtStr.v,
ChunkSize: chunkSize,
})

return agtStr
}

func (b *AgentPlanBuilder) NewString(str string) *AgentStringVar {
v := b.blder.NewStringVar()
v.Value = str

return &AgentStringVar{
owner: b,
v: v,
}
}

func (b *AgentPlanBuilder) NewSignal() *AgentSignalVar {
v := b.blder.NewSignalVar()

return &AgentSignalVar{
owner: b,
v: v,
}
}

// 字节流变量
type AgentStreamVar struct {
owner *AgentPlanBuilder
v *ioswitch.StreamVar
}

func (s *AgentStreamVar) IPFSWrite() *AgentStringVar {
v := s.owner.blder.NewStringVar()

s.owner.Ops = append(s.owner.Ops, &ops.IPFSWrite{
Input: s.v,
FileHash: v,
})

return &AgentStringVar{
owner: s.owner,
v: v,
}
}

func (b *AgentStreamVar) FileWrite(filePath string) {
b.owner.Ops = append(b.owner.Ops, &ops.FileWrite{
Input: b.v,
FilePath: filePath,
})
}

func (b *AgentStreamVar) ChunkedSplit(chunkSize int, streamCount int, paddingZeros bool) []*AgentStreamVar {
var strs []*AgentStreamVar

var outputStrVars []*ioswitch.StreamVar
for i := 0; i < streamCount; i++ {
v := b.owner.blder.NewStreamVar()
strs = append(strs, &AgentStreamVar{
owner: b.owner,
v: v,
})
outputStrVars = append(outputStrVars, v)
}

b.owner.Ops = append(b.owner.Ops, &ops.ChunkedSplit{
Input: b.v,
Outputs: outputStrVars,
ChunkSize: chunkSize,
PaddingZeros: paddingZeros,
})

return strs
}

func (s *AgentStreamVar) Length(length int64) *AgentStreamVar {
agtStr := &AgentStreamVar{
owner: s.owner,
v: s.owner.blder.NewStreamVar(),
}

s.owner.Ops = append(s.owner.Ops, &ops.Length{
Input: s.v,
Output: agtStr.v,
Length: length,
})

return agtStr
}

func (s *AgentStreamVar) To(node cdssdk.Node) *AgentStreamVar {
s.owner.Ops = append(s.owner.Ops, &ops.SendStream{Stream: s.v, Node: node})
s.owner = s.owner.blder.AtAgent(node)

return s
}

func (s *AgentStreamVar) ToExecutor() *ExecutorStreamVar {
s.owner.blder.executorPlan.ops = append(s.owner.blder.executorPlan.ops, &ops.GetStream{
Stream: s.v,
Node: s.owner.Node,
})

return &ExecutorStreamVar{
blder: s.owner.blder,
v: s.v,
}
}

func (s *AgentStreamVar) Clone(cnt int) []*AgentStreamVar {
var strs []*AgentStreamVar

var outputStrVars []*ioswitch.StreamVar
for i := 0; i < cnt; i++ {
v := s.owner.blder.NewStreamVar()
strs = append(strs, &AgentStreamVar{
owner: s.owner,
v: v,
})
outputStrVars = append(outputStrVars, v)
}

s.owner.Ops = append(s.owner.Ops, &ops.CloneStream{
Input: s.v,
Outputs: outputStrVars,
})

return strs
}

// 当流产生时发送一个信号
func (v *AgentStreamVar) OnBegin() (*AgentStreamVar, *AgentSignalVar) {
ns := v.owner.blder.NewStreamVar()
s := v.owner.blder.NewSignalVar()

v.owner.Ops = append(v.owner.Ops, &ops.OnStreamBegin{
Raw: v.v,
New: ns,
Signal: s,
})
return &AgentStreamVar{owner: v.owner, v: ns}, &AgentSignalVar{owner: v.owner, v: s}
}

// 当流结束时发送一个信号
func (v *AgentStreamVar) OnEnd() (*AgentStreamVar, *AgentSignalVar) {
ns := v.owner.blder.NewStreamVar()
s := v.owner.blder.NewSignalVar()

v.owner.Ops = append(v.owner.Ops, &ops.OnStreamEnd{
Raw: v.v,
New: ns,
Signal: s,
})
return &AgentStreamVar{owner: v.owner, v: ns}, &AgentSignalVar{owner: v.owner, v: s}
}

// 将此流暂存,直到一个信号产生后才释放(一个新流)
func (v *AgentStreamVar) HoldUntil(wait *AgentSignalVar) *AgentStreamVar {
nv := v.owner.blder.NewStreamVar()
v.owner.Ops = append(v.owner.Ops, &ops.HoldUntil{
Waits: []*ioswitch.SignalVar{wait.v},
Holds: []ioswitch.Var{v.v},
Emits: []ioswitch.Var{nv},
})
return &AgentStreamVar{owner: v.owner, v: nv}
}

// 字符串变量
type AgentStringVar struct {
owner *AgentPlanBuilder
v *ioswitch.StringVar
}

func (v *AgentStringVar) To(node cdssdk.Node) *AgentStringVar {
v.owner.Ops = append(v.owner.Ops, &ops.SendVar{Var: v.v, Node: node})
v.owner = v.owner.blder.AtAgent(node)

return v
}

func (v *AgentStringVar) ToExecutor() *ExecutorStringVar {
v.owner.blder.executorPlan.ops = append(v.owner.blder.executorPlan.ops, &ops.GetVar{
Var: v.v,
Node: v.owner.Node,
})

return &ExecutorStringVar{
blder: v.owner.blder,
v: v.v,
}
}

func (v *AgentStringVar) Clone() (*AgentStringVar, *AgentStringVar) {
c1 := v.owner.blder.NewStringVar()
c2 := v.owner.blder.NewStringVar()

v.owner.Ops = append(v.owner.Ops, &ops.CloneVar{
Raw: v.v,
Cloneds: []ioswitch.Var{c1, c2},
})

return &AgentStringVar{owner: v.owner, v: c1}, &AgentStringVar{owner: v.owner, v: c2}
}

// 返回cnt+1个复制后的变量
func (v *AgentStringVar) CloneN(cnt int) []*AgentStringVar {
var strs []*AgentStringVar
var cloned []ioswitch.Var
for i := 0; i < cnt+1; i++ {
c := v.owner.blder.NewStringVar()
strs = append(strs, &AgentStringVar{
owner: v.owner,
v: c,
})
cloned = append(cloned, c)
}

v.owner.Ops = append(v.owner.Ops, &ops.CloneVar{
Raw: v.v,
Cloneds: cloned,
})

return strs
}

// 将此变量暂存,直到一个信号产生后才释放(一个新变量)
func (v *AgentStringVar) HoldUntil(wait *AgentSignalVar) *AgentStringVar {
nv := v.owner.blder.NewStringVar()
v.owner.Ops = append(v.owner.Ops, &ops.HoldUntil{
Waits: []*ioswitch.SignalVar{wait.v},
Holds: []ioswitch.Var{v.v},
Emits: []ioswitch.Var{nv},
})
return &AgentStringVar{owner: v.owner, v: nv}
}

type AgentIntVar struct {
owner *AgentPlanBuilder
v *ioswitch.IntVar
}

// 信号变量
type AgentSignalVar struct {
owner *AgentPlanBuilder
v *ioswitch.SignalVar
}

func (v *AgentSignalVar) To(node cdssdk.Node) *AgentSignalVar {
v.owner.Ops = append(v.owner.Ops, &ops.SendVar{Var: v.v, Node: node})
v.owner = v.owner.blder.AtAgent(node)

return v
}

func (v *AgentSignalVar) ToExecutor() *ExecutorSignalVar {
v.owner.blder.executorPlan.ops = append(v.owner.blder.executorPlan.ops, &ops.GetVar{
Var: v.v,
Node: v.owner.Node,
})

return &ExecutorSignalVar{
blder: v.owner.blder,
v: v.v,
}
}

// 当这个信号被产生时,同时产生另外n个信号
func (v *AgentSignalVar) Broadcast(cnt int) []*AgentSignalVar {
var ss []*AgentSignalVar
var targets []*ioswitch.SignalVar

for i := 0; i < cnt; i++ {
c := v.owner.blder.NewSignalVar()
ss = append(ss, &AgentSignalVar{
owner: v.owner,
v: c,
})
targets = append(targets, c)
}

v.owner.Ops = append(v.owner.Ops, &ops.Broadcast{
Source: v.v,
Targets: targets,
})

return ss
}
*/

+ 10
- 20
common/pkgs/ioswitch/plans/fromto.go View File

@@ -3,6 +3,7 @@ package plans
import (
cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
"gitlink.org.cn/cloudream/common/utils/math2"
"gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch/exec"
)

type FromTo struct {
@@ -124,51 +125,40 @@ func (f *FromExecutor) GetDataIndex() int {
return f.DataIndex
}

func (f *FromExecutor) BuildNode(ft *FromTo) Node {
op := Node{
Env: &ExecutorEnv{},
Type: &FromExecutorOp{
Handle: f.Handle,
},
}
op.NewOutputStream(f.DataIndex)
return op
}

type FromNode struct {
type FromWorker struct {
FileHash string
Node *cdssdk.Node
DataIndex int
}

func NewFromNode(fileHash string, node *cdssdk.Node, dataIndex int) *FromNode {
return &FromNode{
func NewFromNode(fileHash string, node *cdssdk.Node, dataIndex int) *FromWorker {
return &FromWorker{
FileHash: fileHash,
Node: node,
DataIndex: dataIndex,
}
}

func (f *FromNode) GetDataIndex() int {
func (f *FromWorker) GetDataIndex() int {
return f.DataIndex
}

type ToExecutor struct {
Handle *ExecutorReadStream
Handle *exec.ExecutorReadStream
DataIndex int
Range Range
}

func NewToExecutor(dataIndex int) (*ToExecutor, *ExecutorReadStream) {
str := ExecutorReadStream{}
func NewToExecutor(dataIndex int) (*ToExecutor, *exec.ExecutorReadStream) {
str := exec.ExecutorReadStream{}
return &ToExecutor{
Handle: &str,
DataIndex: dataIndex,
}, &str
}

func NewToExecutorWithRange(dataIndex int, rng Range) (*ToExecutor, *ExecutorReadStream) {
str := ExecutorReadStream{}
func NewToExecutorWithRange(dataIndex int, rng Range) (*ToExecutor, *exec.ExecutorReadStream) {
str := exec.ExecutorReadStream{}
return &ToExecutor{
Handle: &str,
DataIndex: dataIndex,


+ 338
- 205
common/pkgs/ioswitch/plans/ops.go View File

@@ -6,223 +6,172 @@ import (
"github.com/samber/lo"
"gitlink.org.cn/cloudream/common/pkgs/ipfs"
cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
"gitlink.org.cn/cloudream/common/utils/lo2"
"gitlink.org.cn/cloudream/storage/common/pkgs/ec"
"gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch"
"gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch/dag"
"gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch/exec"
"gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch/ops"
)

type VarIndex int

type StreamVar struct {
DataIndex int
From *Node
Toes []*Node
Var *ioswitch.StreamVar
}

func (v *StreamVar) AddTo(to *Node) {
v.Toes = append(v.Toes, to)
}

func (v *StreamVar) RemoveTo(to *Node) {
v.Toes = lo2.Remove(v.Toes, to)
}

type ValueVarType int

const (
StringValueVar ValueVarType = iota
SignalValueVar
)

type ValueVar struct {
Type ValueVarType
From *Node
Toes []*Node
Var ioswitch.Var
}

func (v *ValueVar) AddTo(to *Node) {
v.Toes = append(v.Toes, to)
}

func (v *ValueVar) RemoveTo(to *Node) {
v.Toes = lo2.Remove(v.Toes, to)
}

type OpEnv interface {
Equals(env OpEnv) bool
}

type AgentEnv struct {
Node cdssdk.Node
}

func (e *AgentEnv) Equals(env OpEnv) bool {
if agentEnv, ok := env.(*AgentEnv); ok {
return e.Node.NodeID == agentEnv.Node.NodeID
}
return false
}

type ExecutorEnv struct{}

func (e *ExecutorEnv) Equals(env OpEnv) bool {
_, ok := env.(*ExecutorEnv)
return ok
}

type OpType interface {
GenerateOp(node *Node, blder *PlanBuilder) error
}

type Node struct {
Env OpEnv // Op将在哪里执行,Agent或者Executor
Type OpType
InputStreams []*StreamVar
OutputStreams []*StreamVar
InputValues []*ValueVar
OutputValues []*ValueVar
}

func (o *Node) NewOutputStream(dataIndex int) *StreamVar {
v := &StreamVar{DataIndex: dataIndex, From: o}
o.OutputStreams = append(o.OutputStreams, v)
return v
}

func (o *Node) AddInputStream(str *StreamVar) {
o.InputStreams = append(o.InputStreams, str)
str.AddTo(o)
}

func (o *Node) ReplaceInputStream(old *StreamVar, new *StreamVar) {
old.RemoveTo(o)
new.AddTo(o)

idx := lo.IndexOf(o.InputStreams, old)
o.InputStreams[idx] = new
}

func (o *Node) NewOutputVar(typ ValueVarType) *ValueVar {
v := &ValueVar{Type: typ, From: o}
o.OutputValues = append(o.OutputValues, v)
return v
}

func (o *Node) AddInputVar(v *ValueVar) {
o.InputValues = append(o.InputValues, v)
v.AddTo(o)
}

func (o *Node) ReplaceInputVar(old *ValueVar, new *ValueVar) {
old.RemoveTo(o)
new.AddTo(o)

idx := lo.IndexOf(o.InputValues, old)
o.InputValues[idx] = new
}

func (o *Node) String() string {
return fmt.Sprintf("Node(%T)", o.Type)
}

type IPFSReadType struct {
FileHash string
Option ipfs.ReadOption
}

func (t *IPFSReadType) GenerateOp(node *Node, blder *PlanBuilder) error {
func (t *IPFSReadType) InitNode(node *Node) {
dag.NodeNewOutputStream(node, VarProps{})
}

func (t *IPFSReadType) GenerateOp(node *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.IPFSRead{
Output: node.OutputStreams[0].Var,
Output: node.OutputStreams[0].Props.Var.(*ioswitch.StreamVar),
FileHash: t.FileHash,
Option: t.Option,
}, node.Env, blder)
return nil
}

func (t *IPFSReadType) String(node *Node) string {
return fmt.Sprintf("IPFSRead[%s,%v+%v]%v%v", t.FileHash, t.Option.Offset, t.Option.Length, formatStreamIO(node), formatValueIO(node))
}

type IPFSWriteType struct {
FileHashStoreKey string
Range Range
}

func (t *IPFSWriteType) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *IPFSWriteType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, 1)
dag.NodeNewOutputValue(node, VarProps{})
}

func (t *IPFSWriteType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.IPFSWrite{
Input: op.InputStreams[0].Var,
FileHash: op.OutputValues[0].Var.(*ioswitch.StringVar),
Input: op.InputStreams[0].Props.Var.(*ioswitch.StreamVar),
FileHash: op.OutputValues[0].Props.Var.(*ioswitch.StringVar),
}, op.Env, blder)
return nil
}

func (t *IPFSWriteType) String(node *Node) string {
return fmt.Sprintf("IPFSWrite[%s,%v+%v](%v>)", t.FileHashStoreKey, t.Range.Offset, t.Range.Length, formatStreamIO(node), formatValueIO(node))
}

type ChunkedSplitType struct {
ChunkSize int
PaddingZeros bool
OutputCount int
ChunkSize int
}

func (t *ChunkedSplitType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, 1)
for i := 0; i < t.OutputCount; i++ {
dag.NodeNewOutputStream(node, VarProps{})
}
}

func (t *ChunkedSplitType) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *ChunkedSplitType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.ChunkedSplit{
Input: op.InputStreams[0].Var,
Input: op.InputStreams[0].Props.Var.(*ioswitch.StreamVar),
Outputs: lo.Map(op.OutputStreams, func(v *StreamVar, idx int) *ioswitch.StreamVar {
return v.Var
return v.Props.Var.(*ioswitch.StreamVar)
}),
ChunkSize: t.ChunkSize,
PaddingZeros: t.PaddingZeros,
PaddingZeros: true,
}, op.Env, blder)
return nil
}

func (t *ChunkedSplitType) String(node *Node) string {
return fmt.Sprintf("ChunkedSplit[%v]", t.ChunkSize, formatStreamIO(node), formatValueIO(node))
}

type ChunkedJoinType struct {
ChunkSize int
InputCount int
ChunkSize int
}

func (t *ChunkedJoinType) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *ChunkedJoinType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, t.InputCount)
dag.NodeNewOutputStream(node, VarProps{})
}

func (t *ChunkedJoinType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.ChunkedJoin{
Inputs: lo.Map(op.InputStreams, func(v *StreamVar, idx int) *ioswitch.StreamVar {
return v.Var
return v.Props.Var.(*ioswitch.StreamVar)
}),
Output: op.OutputStreams[0].Var,
Output: op.OutputStreams[0].Props.Var.(*ioswitch.StreamVar),
ChunkSize: t.ChunkSize,
}, op.Env, blder)
return nil
}

func (t *ChunkedJoinType) String(node *Node) string {
return fmt.Sprintf("ChunkedJoin[%v]", t.ChunkSize, formatStreamIO(node), formatValueIO(node))
}

type CloneStreamType struct{}

func (t *CloneStreamType) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *CloneStreamType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, 1)
}

func (t *CloneStreamType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.CloneStream{
Input: op.InputStreams[0].Var,
Input: op.InputStreams[0].Props.Var.(*ioswitch.StreamVar),
Outputs: lo.Map(op.OutputStreams, func(v *StreamVar, idx int) *ioswitch.StreamVar {
return v.Var
return v.Props.Var.(*ioswitch.StreamVar)
}),
}, op.Env, blder)
return nil
}

func (t *CloneStreamType) NewOutput(node *Node) *StreamVar {
return dag.NodeNewOutputStream(node, VarProps{})
}

func (t *CloneStreamType) String(node *Node) string {
return fmt.Sprintf("CloneStream[]%v%v", formatStreamIO(node), formatValueIO(node))
}

type CloneVarType struct{}

func (t *CloneVarType) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *CloneVarType) InitNode(node *Node) {
dag.NodeDeclareInputValue(node, 1)
}

func (t *CloneVarType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.CloneVar{
Raw: op.InputValues[0].Var,
Raw: op.InputValues[0].Props.Var,
Cloneds: lo.Map(op.OutputValues, func(v *ValueVar, idx int) ioswitch.Var {
return v.Var
return v.Props.Var
}),
}, op.Env, blder)
return nil
}

type MultiplyOp struct {
func (t *CloneVarType) NewOutput(node *Node) *ValueVar {
return dag.NodeNewOutputValue(node, VarProps{})
}

func (t *CloneVarType) String(node *Node) string {
return fmt.Sprintf("CloneVar[]%v%v", formatStreamIO(node), formatValueIO(node))
}

type MultiplyType struct {
EC cdssdk.ECRedundancy
}

func (t *MultiplyOp) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *MultiplyType) InitNode(node *Node) {}

func (t *MultiplyType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
var inputIdxs []int
var outputIdxs []int
for _, in := range op.InputStreams {
inputIdxs = append(inputIdxs, in.DataIndex)
inputIdxs = append(inputIdxs, in.Props.StreamIndex)
}
for _, out := range op.OutputStreams {
outputIdxs = append(outputIdxs, out.DataIndex)
outputIdxs = append(outputIdxs, out.Props.StreamIndex)
}

rs, err := ec.NewRs(t.EC.K, t.EC.N)
@@ -233,169 +182,353 @@ func (t *MultiplyOp) GenerateOp(op *Node, blder *PlanBuilder) error {

addOpByEnv(&ops.ECMultiply{
Coef: coef,
Inputs: lo.Map(op.InputStreams, func(v *StreamVar, idx int) *ioswitch.StreamVar { return v.Var }),
Outputs: lo.Map(op.OutputStreams, func(v *StreamVar, idx int) *ioswitch.StreamVar { return v.Var }),
Inputs: lo.Map(op.InputStreams, func(v *StreamVar, idx int) *ioswitch.StreamVar { return v.Props.Var.(*ioswitch.StreamVar) }),
Outputs: lo.Map(op.OutputStreams, func(v *StreamVar, idx int) *ioswitch.StreamVar { return v.Props.Var.(*ioswitch.StreamVar) }),
ChunkSize: t.EC.ChunkSize,
}, op.Env, blder)
return nil
}

type FileReadOp struct {
func (t *MultiplyType) AddInput(node *Node, str *StreamVar) {
node.InputStreams = append(node.InputStreams, str)
str.To(node, len(node.InputStreams)-1)
}

func (t *MultiplyType) NewOutput(node *Node, dataIndex int) *StreamVar {
return dag.NodeNewOutputStream(node, VarProps{StreamIndex: dataIndex})
}

func (t *MultiplyType) String(node *Node) string {
return fmt.Sprintf("Multiply[]%v%v", formatStreamIO(node), formatValueIO(node))
}

type FileReadType struct {
FilePath string
}

func (t *FileReadOp) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *FileReadType) InitNode(node *Node) {
dag.NodeNewOutputStream(node, VarProps{})
}

func (t *FileReadType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.FileRead{
Output: op.OutputStreams[0].Var,
Output: op.OutputStreams[0].Props.Var.(*ioswitch.StreamVar),
FilePath: t.FilePath,
}, op.Env, blder)
return nil
}

type FileWriteOp struct {
func (t *FileReadType) String(node *Node) string {
return fmt.Sprintf("FileRead[%s]%v%v", t.FilePath, formatStreamIO(node), formatValueIO(node))
}

type FileWriteType struct {
FilePath string
}

func (t *FileWriteOp) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *FileWriteType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, 1)
}

func (t *FileWriteType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.FileWrite{
Input: op.InputStreams[0].Var,
Input: op.InputStreams[0].Props.Var.(*ioswitch.StreamVar),
FilePath: t.FilePath,
}, op.Env, blder)
return nil
}

type FromExecutorOp struct {
Handle *ExecutorWriteStream
type FromExecutorType struct {
Handle *exec.ExecutorWriteStream
}

func (t *FromExecutorType) InitNode(node *Node) {
dag.NodeNewOutputStream(node, VarProps{})
}

func (t *FromExecutorOp) GenerateOp(op *Node, blder *PlanBuilder) error {
t.Handle.Var = op.OutputStreams[0].Var
func (t *FromExecutorType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
t.Handle.Var = op.OutputStreams[0].Props.Var.(*ioswitch.StreamVar)
return nil
}

type ToExecutorOp struct {
Handle *ExecutorReadStream
func (t *FromExecutorType) String(node *Node) string {
return fmt.Sprintf("FromExecutor[]%v%v", formatStreamIO(node), formatValueIO(node))
}

type ToExecutorType struct {
Handle *exec.ExecutorReadStream
Range Range
}

func (t *ToExecutorOp) GenerateOp(op *Node, blder *PlanBuilder) error {
t.Handle.Var = op.InputStreams[0].Var
func (t *ToExecutorType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, 1)
}

func (t *ToExecutorType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
t.Handle.Var = op.InputStreams[0].Props.Var.(*ioswitch.StreamVar)
return nil
}

type StoreOp struct {
func (t *ToExecutorType) String(node *Node) string {
return fmt.Sprintf("ToExecutor[%v+%v]%v%v", t.Range.Offset, t.Range.Length, formatStreamIO(node), formatValueIO(node))
}

type StoreType struct {
StoreKey string
}

func (t *StoreOp) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *StoreType) InitNode(node *Node) {
dag.NodeDeclareInputValue(node, 1)
}

func (t *StoreType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
blder.AtExecutor().AddOp(&ops.Store{
Var: op.InputValues[0].Var,
Var: op.InputValues[0].Props.Var,
Key: t.StoreKey,
Store: blder.ExecutorPlan.StoreMap,
})
return nil
}

type DropOp struct{}
func (t *StoreType) String(node *Node) string {
return fmt.Sprintf("Store[%s]%v%v", t.StoreKey, formatStreamIO(node), formatValueIO(node))
}

type DropType struct{}

func (t *DropType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, 1)
}

func (t *DropOp) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *DropType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.DropStream{
Input: op.InputStreams[0].Var,
Input: op.InputStreams[0].Props.Var.(*ioswitch.StreamVar),
}, op.Env, blder)
return nil
}

type SendStreamOp struct{}
func (t *DropType) String(node *Node) string {
return fmt.Sprintf("Drop[]%v%v", formatStreamIO(node), formatValueIO(node))
}

type SendStreamType struct {
}

func (t *SendStreamType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, 1)
dag.NodeNewOutputStream(node, VarProps{})
}

func (t *SendStreamOp) GenerateOp(op *Node, blder *PlanBuilder) error {
toAgt := op.OutputStreams[0].Toes[0].Env.(*AgentEnv)
func (t *SendStreamType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
toAgt := op.OutputStreams[0].Toes[0].Node.Env.Worker.(*AgentWorker)
addOpByEnv(&ops.SendStream{
Input: op.InputStreams[0].Var,
Send: op.OutputStreams[0].Var,
Input: op.InputStreams[0].Props.Var.(*ioswitch.StreamVar),
Send: op.OutputStreams[0].Props.Var.(*ioswitch.StreamVar),
Node: toAgt.Node,
}, op.Env, blder)
return nil
}

type GetStreamOp struct{}
func (t *SendStreamType) String(node *Node) string {
return fmt.Sprintf("SendStream[]%v%v", formatStreamIO(node), formatValueIO(node))
}

func (t *GetStreamOp) GenerateOp(op *Node, blder *PlanBuilder) error {
fromAgt := op.InputStreams[0].From.Env.(*AgentEnv)
addOpByEnv(&ops.GetStream{
Signal: op.OutputValues[0].Var.(*ioswitch.SignalVar),
Output: op.OutputStreams[0].Var,
Get: op.InputStreams[0].Var,
Node: fromAgt.Node,
}, op.Env, blder)
return nil
type SendVarType struct {
}

type SendVarOp struct{}
func (t *SendVarType) InitNode(node *Node) {
dag.NodeDeclareInputValue(node, 1)
dag.NodeNewOutputValue(node, VarProps{})
}

func (t *SendVarOp) GenerateOp(op *Node, blder *PlanBuilder) error {
toAgt := op.OutputValues[0].Toes[0].Env.(*AgentEnv)
func (t *SendVarType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
toAgt := op.OutputValues[0].Toes[0].Node.Env.Worker.(*AgentWorker)
addOpByEnv(&ops.SendVar{
Input: op.InputValues[0].Var,
Send: op.OutputValues[0].Var,
Input: op.InputValues[0].Props.Var,
Send: op.OutputValues[0].Props.Var,
Node: toAgt.Node,
}, op.Env, blder)
return nil
}

type GetVarOp struct{}
func (t *SendVarType) String(node *Node) string {
return fmt.Sprintf("SendVar[]%v%v", formatStreamIO(node), formatValueIO(node))
}

type GetStreamType struct {
}

func (t *GetVarOp) GenerateOp(op *Node, blder *PlanBuilder) error {
fromAgt := op.InputValues[0].From.Env.(*AgentEnv)
func (t *GetStreamType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, 1)
dag.NodeNewOutputValue(node, VarProps{})
dag.NodeNewOutputStream(node, VarProps{})
}

func (t *GetStreamType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
fromAgt := op.InputStreams[0].From.Node.Env.Worker.(*AgentWorker)
addOpByEnv(&ops.GetStream{
Signal: op.OutputValues[0].Props.Var.(*ioswitch.SignalVar),
Output: op.OutputStreams[0].Props.Var.(*ioswitch.StreamVar),
Target: op.InputStreams[0].Props.Var.(*ioswitch.StreamVar),
Node: fromAgt.Node,
}, op.Env, blder)
return nil
}

func (t *GetStreamType) String(node *Node) string {
return fmt.Sprintf("GetStream[]%v%v", formatStreamIO(node), formatValueIO(node))
}

type GetVaType struct {
}

func (t *GetVaType) InitNode(node *Node) {
dag.NodeDeclareInputValue(node, 1)
dag.NodeNewOutputValue(node, VarProps{})
dag.NodeNewOutputValue(node, VarProps{})
}

func (t *GetVaType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
fromAgt := op.InputValues[0].From.Node.Env.Worker.(*AgentWorker)
addOpByEnv(&ops.GetVar{
Signal: op.OutputValues[0].Var.(*ioswitch.SignalVar),
Output: op.OutputValues[1].Var,
Get: op.InputValues[0].Var,
Signal: op.OutputValues[0].Props.Var.(*ioswitch.SignalVar),
Output: op.OutputValues[1].Props.Var,
Target: op.InputValues[0].Props.Var,
Node: fromAgt.Node,
}, op.Env, blder)
return nil
}

func (t *GetVaType) String(node *Node) string {
return fmt.Sprintf("GetVar[]%v%v", formatStreamIO(node), formatValueIO(node))
}

type RangeType struct {
Range Range
}

func (t *RangeType) GenerateOp(op *Node, blder *PlanBuilder) error {
func (t *RangeType) InitNode(node *Node) {
dag.NodeDeclareInputStream(node, 1)
dag.NodeNewOutputStream(node, VarProps{})
}

func (t *RangeType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
addOpByEnv(&ops.Range{
Input: op.InputStreams[0].Var,
Output: op.OutputStreams[0].Var,
Input: op.InputStreams[0].Props.Var.(*ioswitch.StreamVar),
Output: op.OutputStreams[0].Props.Var.(*ioswitch.StreamVar),
Offset: t.Range.Offset,
Length: t.Range.Length,
}, op.Env, blder)
return nil
}

type HoldUntilOp struct {
func (t *RangeType) String(node *Node) string {
return fmt.Sprintf("Range[%v+%v]%v%v", t.Range.Offset, t.Range.Length, formatStreamIO(node), formatValueIO(node))
}

func (t *HoldUntilOp) GenerateOp(op *Node, blder *PlanBuilder) error {
type HoldUntilType struct {
}

func (t *HoldUntilType) InitNode(node *Node) {
dag.NodeDeclareInputValue(node, 1)
}

func (t *HoldUntilType) GenerateOp(op *Node, blder *exec.PlanBuilder) error {
o := &ops.HoldUntil{
Waits: []*ioswitch.SignalVar{op.InputValues[0].Var.(*ioswitch.SignalVar)},
Waits: []*ioswitch.SignalVar{op.InputValues[0].Props.Var.(*ioswitch.SignalVar)},
}

for i := 0; i < len(op.OutputValues); i++ {
o.Holds = append(o.Holds, op.InputValues[i+1].Var)
o.Emits = append(o.Emits, op.OutputValues[i].Var)
o.Holds = append(o.Holds, op.InputValues[i+1].Props.Var)
o.Emits = append(o.Emits, op.OutputValues[i].Props.Var)
}

for i := 0; i < len(op.OutputStreams); i++ {
o.Holds = append(o.Holds, op.InputStreams[i].Var)
o.Emits = append(o.Emits, op.OutputStreams[i].Var)
o.Holds = append(o.Holds, op.InputStreams[i].Props.Var)
o.Emits = append(o.Emits, op.OutputStreams[i].Props.Var)
}

addOpByEnv(o, op.Env, blder)
return nil
}

func addOpByEnv(op ioswitch.Op, env OpEnv, blder *PlanBuilder) {
switch env := env.(type) {
case *AgentEnv:
blder.AtAgent(env.Node).AddOp(op)
case *ExecutorEnv:
func (t *HoldUntilType) String(node *Node) string {
return fmt.Sprintf("HoldUntil[]%v%v", formatStreamIO(node), formatValueIO(node))
}

func addOpByEnv(op ioswitch.Op, env dag.NodeEnv, blder *exec.PlanBuilder) {
switch env.Type {
case dag.EnvWorker:
blder.AtAgent(env.Worker.(*AgentWorker).Node).AddOp(op)
case dag.EnvExecutor:
blder.AtExecutor().AddOp(op)
}
}

func formatStreamIO(node *Node) string {
is := ""
for i, in := range node.InputStreams {
if i > 0 {
is += ","
}

if in == nil {
is += "."
} else {
is += fmt.Sprintf("%v", in.ID)
}
}

os := ""
for i, out := range node.OutputStreams {
if i > 0 {
os += ","
}

if out == nil {
os += "."
} else {
os += fmt.Sprintf("%v", out.ID)
}
}

if is == "" && os == "" {
return ""
}

return fmt.Sprintf("S{%s>%s}", is, os)
}

func formatValueIO(node *Node) string {
is := ""
for i, in := range node.InputValues {
if i > 0 {
is += ","
}

if in == nil {
is += "."
} else {
is += fmt.Sprintf("%v", in.ID)
}
}

os := ""
for i, out := range node.OutputValues {
if i > 0 {
os += ","
}

if out == nil {
os += "."
} else {
os += fmt.Sprintf("%v", out.ID)
}
}

if is == "" && os == "" {
return ""
}

return fmt.Sprintf("V{%s>%s}", is, os)
}

+ 339
- 519
common/pkgs/ioswitch/plans/parser.go
File diff suppressed because it is too large
View File


Loading…
Cancel
Save