| @@ -3,6 +3,7 @@ package stgmod | |||||
| import ( | import ( | ||||
| "github.com/samber/lo" | "github.com/samber/lo" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/common/utils/sort2" | |||||
| ) | ) | ||||
| type ObjectBlock struct { | type ObjectBlock struct { | ||||
| @@ -48,7 +49,7 @@ func (o *ObjectDetail) GroupBlocks() []GrouppedObjectBlock { | |||||
| grps[block.Index] = grp | grps[block.Index] = grp | ||||
| } | } | ||||
| return lo.Values(grps) | |||||
| return sort2.Sort(lo.Values(grps), func(l, r GrouppedObjectBlock) int { return l.Index - r.Index }) | |||||
| } | } | ||||
| type LocalMachineInfo struct { | type LocalMachineInfo struct { | ||||
| @@ -5,11 +5,17 @@ import ( | |||||
| "io" | "io" | ||||
| "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec" | "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec" | ||||
| "gitlink.org.cn/cloudream/common/pkgs/types" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/common/utils/serder" | |||||
| stgglb "gitlink.org.cn/cloudream/storage/common/globals" | stgglb "gitlink.org.cn/cloudream/storage/common/globals" | ||||
| agtrpc "gitlink.org.cn/cloudream/storage/common/pkgs/grpc/agent" | agtrpc "gitlink.org.cn/cloudream/storage/common/pkgs/grpc/agent" | ||||
| ) | ) | ||||
| var _ = serder.UseTypeUnionExternallyTagged(types.Ref(types.NewTypeUnion[exec.WorkerInfo]( | |||||
| (*AgentWorker)(nil), | |||||
| ))) | |||||
| type AgentWorker struct { | type AgentWorker struct { | ||||
| Node cdssdk.Node | Node cdssdk.Node | ||||
| } | } | ||||
| @@ -89,7 +89,9 @@ type ChunkedSplitType struct { | |||||
| func (t *ChunkedSplitType) InitNode(node *dag.Node) { | func (t *ChunkedSplitType) InitNode(node *dag.Node) { | ||||
| dag.NodeDeclareInputStream(node, 1) | dag.NodeDeclareInputStream(node, 1) | ||||
| for i := 0; i < t.OutputCount; i++ { | for i := 0; i < t.OutputCount; i++ { | ||||
| dag.NodeNewOutputStream(node, &ioswitch2.VarProps{}) | |||||
| dag.NodeNewOutputStream(node, &ioswitch2.VarProps{ | |||||
| StreamIndex: i, | |||||
| }) | |||||
| } | } | ||||
| } | } | ||||
| @@ -104,7 +104,7 @@ func (t *CloneVarType) GenerateOp(op *dag.Node) (exec.Op, error) { | |||||
| } | } | ||||
| func (t *CloneVarType) NewOutput(node *dag.Node) *dag.ValueVar { | func (t *CloneVarType) NewOutput(node *dag.Node) *dag.ValueVar { | ||||
| return dag.NodeNewOutputValue(node, nil) | |||||
| return dag.NodeNewOutputValue(node, node.InputValues[0].Type, nil) | |||||
| } | } | ||||
| func (t *CloneVarType) String(node *dag.Node) string { | func (t *CloneVarType) String(node *dag.Node) string { | ||||
| @@ -195,26 +195,19 @@ func (o *ECMultiply) Execute(ctx context.Context, e *exec.Executor) error { | |||||
| } | } | ||||
| type MultiplyType struct { | type MultiplyType struct { | ||||
| EC cdssdk.ECRedundancy | |||||
| EC cdssdk.ECRedundancy | |||||
| InputIndexes []int | |||||
| OutputIndexes []int | |||||
| } | } | ||||
| func (t *MultiplyType) InitNode(node *dag.Node) {} | func (t *MultiplyType) InitNode(node *dag.Node) {} | ||||
| func (t *MultiplyType) GenerateOp(op *dag.Node) (exec.Op, error) { | func (t *MultiplyType) GenerateOp(op *dag.Node) (exec.Op, error) { | ||||
| var inputIdxs []int | |||||
| var outputIdxs []int | |||||
| for _, in := range op.InputStreams { | |||||
| inputIdxs = append(inputIdxs, ioswitch2.SProps(in).StreamIndex) | |||||
| } | |||||
| for _, out := range op.OutputStreams { | |||||
| outputIdxs = append(outputIdxs, ioswitch2.SProps(out).StreamIndex) | |||||
| } | |||||
| rs, err := ec.NewRs(t.EC.K, t.EC.N) | rs, err := ec.NewRs(t.EC.K, t.EC.N) | ||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| coef, err := rs.GenerateMatrix(inputIdxs, outputIdxs) | |||||
| coef, err := rs.GenerateMatrix(t.InputIndexes, t.OutputIndexes) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| @@ -227,12 +220,14 @@ func (t *MultiplyType) GenerateOp(op *dag.Node) (exec.Op, error) { | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| func (t *MultiplyType) AddInput(node *dag.Node, str *dag.StreamVar) { | |||||
| func (t *MultiplyType) AddInput(node *dag.Node, str *dag.StreamVar, dataIndex int) { | |||||
| t.InputIndexes = append(t.InputIndexes, dataIndex) | |||||
| node.InputStreams = append(node.InputStreams, str) | node.InputStreams = append(node.InputStreams, str) | ||||
| str.To(node, len(node.InputStreams)-1) | str.To(node, len(node.InputStreams)-1) | ||||
| } | } | ||||
| func (t *MultiplyType) NewOutput(node *dag.Node, dataIndex int) *dag.StreamVar { | func (t *MultiplyType) NewOutput(node *dag.Node, dataIndex int) *dag.StreamVar { | ||||
| t.OutputIndexes = append(t.OutputIndexes, dataIndex) | |||||
| return dag.NodeNewOutputStream(node, &ioswitch2.VarProps{StreamIndex: dataIndex}) | return dag.NodeNewOutputStream(node, &ioswitch2.VarProps{StreamIndex: dataIndex}) | ||||
| } | } | ||||
| @@ -114,7 +114,7 @@ type IPFSWriteType struct { | |||||
| func (t *IPFSWriteType) InitNode(node *dag.Node) { | func (t *IPFSWriteType) InitNode(node *dag.Node) { | ||||
| dag.NodeDeclareInputStream(node, 1) | dag.NodeDeclareInputStream(node, 1) | ||||
| dag.NodeNewOutputValue(node, &ioswitch2.VarProps{}) | |||||
| dag.NodeNewOutputValue(node, dag.StringValueVar, &ioswitch2.VarProps{}) | |||||
| } | } | ||||
| func (t *IPFSWriteType) GenerateOp(op *dag.Node) (exec.Op, error) { | func (t *IPFSWriteType) GenerateOp(op *dag.Node) (exec.Op, error) { | ||||
| @@ -35,7 +35,7 @@ type ParseContext struct { | |||||
| } | } | ||||
| func (p *DefaultParser) Parse(ft ioswitch2.FromTo, blder *exec.PlanBuilder) error { | func (p *DefaultParser) Parse(ft ioswitch2.FromTo, blder *exec.PlanBuilder) error { | ||||
| ctx := ParseContext{Ft: ft} | |||||
| ctx := ParseContext{Ft: ft, DAG: dag.NewGraph()} | |||||
| // 分成两个阶段: | // 分成两个阶段: | ||||
| // 1. 基于From和To生成更多指令,初步匹配to的需求 | // 1. 基于From和To生成更多指令,初步匹配to的需求 | ||||
| @@ -136,17 +136,15 @@ func (p *DefaultParser) calcStreamRange(ctx *ParseContext) { | |||||
| func (p *DefaultParser) extend(ctx *ParseContext, ft ioswitch2.FromTo) error { | func (p *DefaultParser) extend(ctx *ParseContext, ft ioswitch2.FromTo) error { | ||||
| for _, fr := range ft.Froms { | for _, fr := range ft.Froms { | ||||
| _, err := p.buildFromNode(ctx, &ft, fr) | |||||
| frNode, err := p.buildFromNode(ctx, &ft, fr) | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| // 对于完整文件的From,生成Split指令 | // 对于完整文件的From,生成Split指令 | ||||
| if fr.GetDataIndex() == -1 { | if fr.GetDataIndex() == -1 { | ||||
| n, _ := dag.NewNode(ctx.DAG, &ops2.ChunkedSplitType{ChunkSize: p.EC.ChunkSize, OutputCount: p.EC.K}, &ioswitch2.NodeProps{}) | |||||
| for i := 0; i < p.EC.K; i++ { | |||||
| ioswitch2.SProps(n.OutputStreams[i]).StreamIndex = i | |||||
| } | |||||
| node, _ := dag.NewNode(ctx.DAG, &ops2.ChunkedSplitType{ChunkSize: p.EC.ChunkSize, OutputCount: p.EC.K}, &ioswitch2.NodeProps{}) | |||||
| frNode.OutputStreams[0].To(node, 0) | |||||
| } | } | ||||
| } | } | ||||
| @@ -170,7 +168,7 @@ loop: | |||||
| }, &ioswitch2.NodeProps{}) | }, &ioswitch2.NodeProps{}) | ||||
| for _, s := range ecInputStrs { | for _, s := range ecInputStrs { | ||||
| mulType.AddInput(mulNode, s) | |||||
| mulType.AddInput(mulNode, s, ioswitch2.SProps(s).StreamIndex) | |||||
| } | } | ||||
| for i := 0; i < p.EC.N; i++ { | for i := 0; i < p.EC.N; i++ { | ||||
| mulType.NewOutput(mulNode, i) | mulType.NewOutput(mulNode, i) | ||||
| @@ -247,6 +245,7 @@ func (p *DefaultParser) buildFromNode(ctx *ParseContext, ft *ioswitch2.FromTo, f | |||||
| if f.Node != nil { | if f.Node != nil { | ||||
| n.Env.ToEnvWorker(&ioswitch2.AgentWorker{Node: *f.Node}) | n.Env.ToEnvWorker(&ioswitch2.AgentWorker{Node: *f.Node}) | ||||
| n.Env.Pinned = true | |||||
| } | } | ||||
| return n, nil | return n, nil | ||||
| @@ -254,6 +253,7 @@ func (p *DefaultParser) buildFromNode(ctx *ParseContext, ft *ioswitch2.FromTo, f | |||||
| case *ioswitch2.FromDriver: | case *ioswitch2.FromDriver: | ||||
| n, _ := dag.NewNode(ctx.DAG, &ops.FromDriverType{Handle: f.Handle}, &ioswitch2.NodeProps{From: f}) | n, _ := dag.NewNode(ctx.DAG, &ops.FromDriverType{Handle: f.Handle}, &ioswitch2.NodeProps{From: f}) | ||||
| n.Env.ToEnvDriver() | n.Env.ToEnvDriver() | ||||
| n.Env.Pinned = true | |||||
| ioswitch2.SProps(n.OutputStreams[0]).StreamIndex = f.DataIndex | ioswitch2.SProps(n.OutputStreams[0]).StreamIndex = f.DataIndex | ||||
| if f.DataIndex == -1 { | if f.DataIndex == -1 { | ||||
| @@ -280,12 +280,15 @@ func (p *DefaultParser) buildToNode(ctx *ParseContext, ft *ioswitch2.FromTo, t i | |||||
| }, &ioswitch2.NodeProps{ | }, &ioswitch2.NodeProps{ | ||||
| To: t, | To: t, | ||||
| }) | }) | ||||
| n.Env.ToEnvWorker(&ioswitch2.AgentWorker{Node: t.Node}) | |||||
| n.Env.Pinned = true | |||||
| return n, nil | return n, nil | ||||
| case *ioswitch2.ToDriver: | case *ioswitch2.ToDriver: | ||||
| n, _ := dag.NewNode(ctx.DAG, &ops.ToDriverType{Handle: t.Handle, Range: t.Range}, &ioswitch2.NodeProps{To: t}) | n, _ := dag.NewNode(ctx.DAG, &ops.ToDriverType{Handle: t.Handle, Range: t.Range}, &ioswitch2.NodeProps{To: t}) | ||||
| n.Env.ToEnvDriver() | n.Env.ToEnvDriver() | ||||
| n.Env.Pinned = true | |||||
| return n, nil | return n, nil | ||||
| @@ -324,9 +327,11 @@ func (p *DefaultParser) removeUnusedMultiplyOutput(ctx *ParseContext) bool { | |||||
| } | } | ||||
| node.OutputStreams[i2] = nil | node.OutputStreams[i2] = nil | ||||
| typ.OutputIndexes[i2] = -2 | |||||
| changed = true | changed = true | ||||
| } | } | ||||
| node.OutputStreams = lo2.RemoveAllDefault(node.OutputStreams) | node.OutputStreams = lo2.RemoveAllDefault(node.OutputStreams) | ||||
| typ.OutputIndexes = lo2.RemoveAll(typ.OutputIndexes, -2) | |||||
| // 如果所有输出流都被删除,则删除该指令 | // 如果所有输出流都被删除,则删除该指令 | ||||
| if len(node.OutputStreams) == 0 { | if len(node.OutputStreams) == 0 { | ||||
| @@ -422,6 +427,10 @@ func (p *DefaultParser) omitSplitJoin(ctx *ParseContext) bool { | |||||
| func (p *DefaultParser) pin(ctx *ParseContext) bool { | func (p *DefaultParser) pin(ctx *ParseContext) bool { | ||||
| changed := false | changed := false | ||||
| ctx.DAG.Walk(func(node *dag.Node) bool { | ctx.DAG.Walk(func(node *dag.Node) bool { | ||||
| if node.Env.Pinned { | |||||
| return true | |||||
| } | |||||
| var toEnv *dag.NodeEnv | var toEnv *dag.NodeEnv | ||||
| for _, out := range node.OutputStreams { | for _, out := range node.OutputStreams { | ||||
| for _, to := range out.Toes { | for _, to := range out.Toes { | ||||
| @@ -496,12 +505,11 @@ func (p *DefaultParser) storeIPFSWriteResult(ctx *ParseContext) { | |||||
| return true | return true | ||||
| } | } | ||||
| n := ctx.DAG.NewNode(&ops.StoreType{ | |||||
| n, t := dag.NewNode(ctx.DAG, &ops.StoreType{ | |||||
| StoreKey: typ.FileHashStoreKey, | StoreKey: typ.FileHashStoreKey, | ||||
| }, &ioswitch2.NodeProps{}) | }, &ioswitch2.NodeProps{}) | ||||
| n.Env.ToEnvDriver() | n.Env.ToEnvDriver() | ||||
| node.OutputValues[0].To(n, 0) | |||||
| t.Store(n, node.OutputValues[0]) | |||||
| return true | return true | ||||
| }) | }) | ||||
| } | } | ||||
| @@ -564,7 +572,9 @@ func (p *DefaultParser) generateClone(ctx *ParseContext) { | |||||
| n, t := dag.NewNode(ctx.DAG, &ops2.CloneStreamType{}, &ioswitch2.NodeProps{}) | n, t := dag.NewNode(ctx.DAG, &ops2.CloneStreamType{}, &ioswitch2.NodeProps{}) | ||||
| n.Env = node.Env | n.Env = node.Env | ||||
| for _, to := range out.Toes { | for _, to := range out.Toes { | ||||
| t.NewOutput(node).To(to.Node, to.SlotIndex) | |||||
| str := t.NewOutput(n) | |||||
| str.Props = &ioswitch2.VarProps{StreamIndex: ioswitch2.SProps(out).StreamIndex} | |||||
| str.To(to.Node, to.SlotIndex) | |||||
| } | } | ||||
| out.Toes = nil | out.Toes = nil | ||||
| out.To(n, 0) | out.To(n, 0) | ||||
| @@ -578,7 +588,7 @@ func (p *DefaultParser) generateClone(ctx *ParseContext) { | |||||
| n, t := dag.NewNode(ctx.DAG, &ops2.CloneVarType{}, &ioswitch2.NodeProps{}) | n, t := dag.NewNode(ctx.DAG, &ops2.CloneVarType{}, &ioswitch2.NodeProps{}) | ||||
| n.Env = node.Env | n.Env = node.Env | ||||
| for _, to := range out.Toes { | for _, to := range out.Toes { | ||||
| t.NewOutput(node).To(to.Node, to.SlotIndex) | |||||
| t.NewOutput(n).To(to.Node, to.SlotIndex) | |||||
| } | } | ||||
| out.Toes = nil | out.Toes = nil | ||||
| out.To(n, 0) | out.To(n, 0) | ||||
| @@ -104,7 +104,7 @@ func (t *CloneVarType) GenerateOp(op *dag.Node) (exec.Op, error) { | |||||
| } | } | ||||
| func (t *CloneVarType) NewOutput(node *dag.Node) *dag.ValueVar { | func (t *CloneVarType) NewOutput(node *dag.Node) *dag.ValueVar { | ||||
| return dag.NodeNewOutputValue(node, nil) | |||||
| return dag.NodeNewOutputValue(node, node.InputValues[0].Type, nil) | |||||
| } | } | ||||
| func (t *CloneVarType) String(node *dag.Node) string { | func (t *CloneVarType) String(node *dag.Node) string { | ||||
| @@ -114,7 +114,7 @@ type IPFSWriteType struct { | |||||
| func (t *IPFSWriteType) InitNode(node *dag.Node) { | func (t *IPFSWriteType) InitNode(node *dag.Node) { | ||||
| dag.NodeDeclareInputStream(node, 1) | dag.NodeDeclareInputStream(node, 1) | ||||
| dag.NodeNewOutputValue(node, &ioswitch2.VarProps{}) | |||||
| dag.NodeNewOutputValue(node, dag.StringValueVar, &ioswitch2.VarProps{}) | |||||
| } | } | ||||
| func (t *IPFSWriteType) GenerateOp(op *dag.Node) (exec.Op, error) { | func (t *IPFSWriteType) GenerateOp(op *dag.Node) (exec.Op, error) { | ||||
| @@ -89,6 +89,7 @@ func buildFromNode(ctx *GenerateContext, f ioswitchlrc.From) (*dag.Node, error) | |||||
| if f.Node != nil { | if f.Node != nil { | ||||
| n.Env.ToEnvWorker(&ioswitchlrc.AgentWorker{Node: *f.Node}) | n.Env.ToEnvWorker(&ioswitchlrc.AgentWorker{Node: *f.Node}) | ||||
| n.Env.Pinned = true | |||||
| } | } | ||||
| return n, nil | return n, nil | ||||
| @@ -96,6 +97,7 @@ func buildFromNode(ctx *GenerateContext, f ioswitchlrc.From) (*dag.Node, error) | |||||
| case *ioswitchlrc.FromDriver: | case *ioswitchlrc.FromDriver: | ||||
| n, _ := dag.NewNode(ctx.DAG, &ops.FromDriverType{Handle: f.Handle}, &ioswitchlrc.NodeProps{From: f}) | n, _ := dag.NewNode(ctx.DAG, &ops.FromDriverType{Handle: f.Handle}, &ioswitchlrc.NodeProps{From: f}) | ||||
| n.Env.ToEnvDriver() | n.Env.ToEnvDriver() | ||||
| n.Env.Pinned = true | |||||
| ioswitchlrc.SProps(n.OutputStreams[0]).StreamIndex = f.DataIndex | ioswitchlrc.SProps(n.OutputStreams[0]).StreamIndex = f.DataIndex | ||||
| if f.DataIndex == -1 { | if f.DataIndex == -1 { | ||||
| @@ -122,12 +124,15 @@ func buildToNode(ctx *GenerateContext, t ioswitchlrc.To) (*dag.Node, error) { | |||||
| }, &ioswitchlrc.NodeProps{ | }, &ioswitchlrc.NodeProps{ | ||||
| To: t, | To: t, | ||||
| }) | }) | ||||
| n.Env.ToEnvWorker(&ioswitchlrc.AgentWorker{Node: t.Node}) | |||||
| n.Env.Pinned = true | |||||
| return n, nil | return n, nil | ||||
| case *ioswitchlrc.ToDriver: | case *ioswitchlrc.ToDriver: | ||||
| n, _ := dag.NewNode(ctx.DAG, &ops.ToDriverType{Handle: t.Handle, Range: t.Range}, &ioswitchlrc.NodeProps{To: t}) | n, _ := dag.NewNode(ctx.DAG, &ops.ToDriverType{Handle: t.Handle, Range: t.Range}, &ioswitchlrc.NodeProps{To: t}) | ||||
| n.Env.ToEnvDriver() | n.Env.ToEnvDriver() | ||||
| n.Env.Pinned = true | |||||
| return n, nil | return n, nil | ||||
| @@ -142,6 +147,10 @@ func buildToNode(ctx *GenerateContext, t ioswitchlrc.To) (*dag.Node, error) { | |||||
| func pin(ctx *GenerateContext) bool { | func pin(ctx *GenerateContext) bool { | ||||
| changed := false | changed := false | ||||
| ctx.DAG.Walk(func(node *dag.Node) bool { | ctx.DAG.Walk(func(node *dag.Node) bool { | ||||
| if node.Env.Pinned { | |||||
| return true | |||||
| } | |||||
| var toEnv *dag.NodeEnv | var toEnv *dag.NodeEnv | ||||
| for _, out := range node.OutputStreams { | for _, out := range node.OutputStreams { | ||||
| for _, to := range out.Toes { | for _, to := range out.Toes { | ||||