You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ec.go 4.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package opt
  2. import (
  3. "gitlink.org.cn/cloudream/common/utils/lo2"
  4. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch/dag"
  5. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2"
  6. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/ops2"
  7. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/parser/state"
  8. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory"
  9. stgtypes "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
  10. )
  11. // 减少未使用的Multiply指令的输出流。如果减少到0,则删除该指令
  12. func RemoveUnusedMultiplyOutput(ctx *state.GenerateState) bool {
  13. changed := false
  14. dag.WalkOnlyType[*ops2.ECMultiplyNode](ctx.DAG.Graph, func(node *ops2.ECMultiplyNode) bool {
  15. outArr := node.OutputStreams().Slots.RawArray()
  16. for i2, out := range outArr {
  17. if out.Dst.Len() > 0 {
  18. continue
  19. }
  20. outArr[i2] = nil
  21. node.OutputIndexes[i2] = -2
  22. changed = true
  23. }
  24. node.OutputStreams().Slots.SetRawArray(lo2.RemoveAllDefault(outArr))
  25. node.OutputIndexes = lo2.RemoveAll(node.OutputIndexes, -2)
  26. // 如果所有输出流都被删除,则删除该指令
  27. if node.OutputStreams().Len() == 0 {
  28. node.RemoveAllInputs()
  29. ctx.DAG.RemoveNode(node)
  30. changed = true
  31. }
  32. return true
  33. })
  34. return changed
  35. }
  36. // 替换ECMultiply指令
  37. func UseECMultiplier(ctx *state.GenerateState) {
  38. dag.WalkOnlyType[*ops2.ECMultiplyNode](ctx.DAG.Graph, func(mulNode *ops2.ECMultiplyNode) bool {
  39. if mulNode.OutputStreams().Len() == 0 {
  40. return true
  41. }
  42. // 暂不支持编解码流的一部分
  43. if ctx.StreamRange.Offset != 0 || ctx.StreamRange.Length != nil {
  44. return true
  45. }
  46. var to *ioswitch2.ToShardStore
  47. var bwNodes []*ops2.BaseWriteNode
  48. // 所有的输出流必须有且只有一个相同的目的地
  49. // 暂时只支持分片存储
  50. for i := 0; i < mulNode.OutputStreams().Len(); i++ {
  51. if mulNode.OutputStreams().Get(i).Dst.Len() != 1 {
  52. return true
  53. }
  54. dstNode := mulNode.OutputStreams().Get(i).Dst.Get(0)
  55. swNode, ok := dstNode.(*ops2.BaseWriteNode)
  56. if !ok {
  57. return true
  58. }
  59. toShard, ok := swNode.To.(*ioswitch2.ToShardStore)
  60. if !ok {
  61. return true
  62. }
  63. if to == nil {
  64. to = toShard
  65. } else if to.UserSpace.UserSpace.UserSpaceID != swNode.UserSpace.UserSpace.UserSpaceID {
  66. return true
  67. }
  68. bwNodes = append(bwNodes, swNode)
  69. }
  70. _, err := factory.GetBuilder(&to.UserSpace).CreateECMultiplier(true)
  71. if err != nil {
  72. return true
  73. }
  74. // 每一个输入流都必须直接来自于存储服务,而且要支持通过HTTP读取文件
  75. var brNodes []*ops2.BaseReadDynNode
  76. var fromShards []*ioswitch2.FromShardStore
  77. for i := 0; i < mulNode.InputStreams().Len(); i++ {
  78. inNode := mulNode.InputStreams().Get(i).Src
  79. brNode, ok := inNode.(*ops2.BaseReadDynNode)
  80. if !ok {
  81. return true
  82. }
  83. fromShard, ok := brNode.From.(*ioswitch2.FromShardStore)
  84. if !ok {
  85. return true
  86. }
  87. store, err := factory.GetBuilder(&brNode.UserSpace).CreateShardStore(true)
  88. if err != nil {
  89. return true
  90. }
  91. _, ok = store.(stgtypes.HTTPShardRead)
  92. if !ok {
  93. return true
  94. }
  95. brNodes = append(brNodes, brNode)
  96. fromShards = append(fromShards, fromShard)
  97. }
  98. // 检查满足条件后,替换ECMultiply指令
  99. callMul := ctx.DAG.NewCallECMultiplier(to.UserSpace)
  100. if err := setEnvBySpace(callMul, &to.UserSpace); err != nil {
  101. return true
  102. }
  103. callMul.InitFrom(mulNode)
  104. for i, brNode := range brNodes {
  105. brNode.Output().Var().NotTo(mulNode)
  106. // 只有完全没有输出的ShardReadNode才可以被删除
  107. if brNode.Output().Var().Dst.Len() == 0 {
  108. ctx.DAG.RemoveNode(brNode)
  109. }
  110. hbr := ctx.DAG.NewGetShardHTTPRequest(brNode.UserSpace, fromShards[i].FileHash)
  111. hbr.Env().ToEnvDriver(true)
  112. hbr.HTTPRequestVar().ToSlot(callMul.HTTPRequestSlot(i))
  113. }
  114. for i, bwNode := range bwNodes {
  115. ctx.DAG.RemoveNode(bwNode)
  116. for _, dstSlot := range bwNode.FileInfoVar().ListDstSlots() {
  117. callMul.FileInfoVar(i).ToSlot(dstSlot)
  118. }
  119. }
  120. ctx.DAG.RemoveNode(mulNode)
  121. return true
  122. })
  123. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。