|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- package opt
-
- import (
- "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag"
- "gitlink.org.cn/cloudream/common/utils/lo2"
- "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2"
- "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/ops2"
- "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/parser/state"
- "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory"
- "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
- )
-
- // 减少未使用的Multiply指令的输出流。如果减少到0,则删除该指令
- func RemoveUnusedMultiplyOutput(ctx *state.GenerateState) bool {
- changed := false
- dag.WalkOnlyType[*ops2.ECMultiplyNode](ctx.DAG.Graph, func(node *ops2.ECMultiplyNode) bool {
- outArr := node.OutputStreams().Slots.RawArray()
- for i2, out := range outArr {
- if out.Dst.Len() > 0 {
- continue
- }
-
- outArr[i2] = nil
- node.OutputIndexes[i2] = -2
- changed = true
- }
-
- node.OutputStreams().Slots.SetRawArray(lo2.RemoveAllDefault(outArr))
- node.OutputIndexes = lo2.RemoveAll(node.OutputIndexes, -2)
-
- // 如果所有输出流都被删除,则删除该指令
- if node.OutputStreams().Len() == 0 {
- node.RemoveAllInputs()
- ctx.DAG.RemoveNode(node)
- changed = true
- }
-
- return true
- })
- return changed
- }
-
- // 替换ECMultiply指令
- func UseECMultiplier(ctx *state.GenerateState) {
- dag.WalkOnlyType[*ops2.ECMultiplyNode](ctx.DAG.Graph, func(mulNode *ops2.ECMultiplyNode) bool {
- if mulNode.OutputStreams().Len() == 0 {
- return true
- }
-
- // 暂不支持编解码流的一部分
- if ctx.StreamRange.Offset != 0 || ctx.StreamRange.Length != nil {
- return true
- }
-
- var to *ioswitch2.ToShardStore
- var bwNodes []*ops2.BaseWriteNode
- // 所有的输出流必须有且只有一个相同的目的地
- // 暂时只支持分片存储
- for i := 0; i < mulNode.OutputStreams().Len(); i++ {
- if mulNode.OutputStreams().Get(i).Dst.Len() != 1 {
- return true
- }
-
- dstNode := mulNode.OutputStreams().Get(i).Dst.Get(0)
- swNode, ok := dstNode.(*ops2.BaseWriteNode)
- if !ok {
- return true
- }
-
- toShard, ok := swNode.To.(*ioswitch2.ToShardStore)
- if !ok {
- return true
- }
-
- if to == nil {
- to = toShard
- } else if to.UserSpace.UserSpace.UserSpaceID != swNode.UserSpace.UserSpace.UserSpaceID {
- return true
- }
- bwNodes = append(bwNodes, swNode)
- }
- _, err := factory.GetBuilder(&to.UserSpace).CreateECMultiplier(true)
- if err != nil {
- return true
- }
-
- // 每一个输入流都必须直接来自于存储服务,而且要支持通过HTTP读取文件
- var brNodes []*ops2.BaseReadDynNode
- var fromShards []*ioswitch2.FromShardStore
- for i := 0; i < mulNode.InputStreams().Len(); i++ {
- inNode := mulNode.InputStreams().Get(i).Src
- brNode, ok := inNode.(*ops2.BaseReadDynNode)
- if !ok {
- return true
- }
- fromShard, ok := brNode.From.(*ioswitch2.FromShardStore)
- if !ok {
- return true
- }
-
- store, err := factory.GetBuilder(&brNode.UserSpace).CreateShardStore(true)
- if err != nil {
- return true
- }
- _, ok = store.(types.HTTPShardRead)
- if !ok {
- return true
- }
-
- brNodes = append(brNodes, brNode)
- fromShards = append(fromShards, fromShard)
- }
-
- // 检查满足条件后,替换ECMultiply指令
- callMul := ctx.DAG.NewCallECMultiplier(to.UserSpace)
- if err := setEnvBySpace(callMul, &to.UserSpace); err != nil {
- return true
- }
-
- callMul.InitFrom(mulNode)
- for i, brNode := range brNodes {
- brNode.Output().Var().NotTo(mulNode)
- // 只有完全没有输出的ShardReadNode才可以被删除
- if brNode.Output().Var().Dst.Len() == 0 {
- ctx.DAG.RemoveNode(brNode)
- }
-
- hbr := ctx.DAG.NewGetShardHTTPRequest(brNode.UserSpace, fromShards[i].FileHash)
- hbr.Env().ToEnvDriver(true)
- hbr.HTTPRequestVar().ToSlot(callMul.HTTPRequestSlot(i))
- }
-
- for i, bwNode := range bwNodes {
- ctx.DAG.RemoveNode(bwNode)
-
- for _, dstSlot := range bwNode.FileInfoVar().ListDstSlots() {
- callMul.FileInfoVar(i).ToSlot(dstSlot)
- }
- }
-
- ctx.DAG.RemoveNode(mulNode)
- return true
- })
- }
|