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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package opt
  2. import (
  3. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag"
  4. "gitlink.org.cn/cloudream/common/utils/lo2"
  5. "gitlink.org.cn/cloudream/storage2/common/pkgs/ioswitch2"
  6. "gitlink.org.cn/cloudream/storage2/common/pkgs/ioswitch2/ops2"
  7. "gitlink.org.cn/cloudream/storage2/common/pkgs/ioswitch2/parser/state"
  8. "gitlink.org.cn/cloudream/storage2/common/pkgs/storage/factory"
  9. cortypes "gitlink.org.cn/cloudream/storage2/coordinator/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 swNodes []*ops2.ShardWriteNode
  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.ShardWriteNode)
  56. if !ok {
  57. return true
  58. }
  59. if to == nil {
  60. to = swNode.To
  61. } else if to.Space.UserSpace.StorageID != swNode.UserSpace.UserSpace.StorageID {
  62. return true
  63. }
  64. swNodes = append(swNodes, swNode)
  65. }
  66. _, err := factory.GetBuilder(&to.Space).CreateECMultiplier()
  67. if err != nil {
  68. return true
  69. }
  70. // 每一个输入流都必须直接来自于存储服务,而且要支持通过HTTP读取文件
  71. var srNodes []*ops2.ShardReadNode
  72. for i := 0; i < mulNode.InputStreams().Len(); i++ {
  73. inNode := mulNode.InputStreams().Get(i).Src
  74. srNode, ok := inNode.(*ops2.ShardReadNode)
  75. if !ok {
  76. return true
  77. }
  78. if !factory.GetBuilder(&srNode.From.Space).FeatureDesc().HasBypassHTTPRead() {
  79. return true
  80. }
  81. srNodes = append(srNodes, srNode)
  82. }
  83. // 检查满足条件后,替换ECMultiply指令
  84. callMul := ctx.DAG.NewCallECMultiplier(to.Space)
  85. switch addr := to.Hub.Address.(type) {
  86. case *cortypes.HttpAddressInfo:
  87. callMul.Env().ToEnvWorker(&ioswitch2.HttpHubWorker{Hub: to.Hub})
  88. callMul.Env().Pinned = true
  89. case *cortypes.GRPCAddressInfo:
  90. callMul.Env().ToEnvWorker(&ioswitch2.AgentWorker{Hub: to.Hub, Address: *addr})
  91. callMul.Env().Pinned = true
  92. default:
  93. return true
  94. }
  95. callMul.InitFrom(mulNode)
  96. for i, srNode := range srNodes {
  97. srNode.Output().Var().NotTo(mulNode)
  98. // 只有完全没有输出的ShardReadNode才可以被删除
  99. if srNode.Output().Var().Dst.Len() == 0 {
  100. ctx.DAG.RemoveNode(srNode)
  101. delete(ctx.FromNodes, srNode.From)
  102. }
  103. hbr := ctx.DAG.NewBypassFromShardStoreHTTP(srNode.UserSpace, srNode.From.FileHash)
  104. hbr.Env().CopyFrom(srNode.Env())
  105. hbr.HTTPRequestVar().ToSlot(callMul.InputSlot(i))
  106. }
  107. for i, swNode := range swNodes {
  108. ctx.DAG.RemoveNode(swNode)
  109. delete(ctx.ToNodes, swNode.To)
  110. bs := ctx.DAG.NewBypassToShardStore(to.Space, swNode.FileHashStoreKey)
  111. bs.Env().CopyFrom(swNode.Env())
  112. callMul.OutputVar(i).ToSlot(bs.BypassFileInfoSlot())
  113. bs.BypassCallbackVar().ToSlot(callMul.BypassCallbackSlot(i))
  114. }
  115. ctx.DAG.RemoveNode(mulNode)
  116. return true
  117. })
  118. }

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