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.

chunked.go 2.7 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package opt
  2. import (
  3. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag"
  4. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2/ops2"
  5. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2/parser/state"
  6. )
  7. // 删除输出流未被使用的Join指令
  8. func RemoveUnusedJoin(ctx *state.GenerateState) bool {
  9. changed := false
  10. dag.WalkOnlyType[*ops2.ChunkedJoinNode](ctx.DAG.Graph, func(node *ops2.ChunkedJoinNode) bool {
  11. if node.Joined().Dst.Len() > 0 {
  12. return true
  13. }
  14. node.RemoveAllInputs()
  15. ctx.DAG.RemoveNode(node)
  16. return true
  17. })
  18. return changed
  19. }
  20. // 删除未使用的Split指令
  21. func RemoveUnusedSplit(ctx *state.GenerateState) bool {
  22. changed := false
  23. dag.WalkOnlyType[*ops2.ChunkedSplitNode](ctx.DAG.Graph, func(typ *ops2.ChunkedSplitNode) bool {
  24. // Split出来的每一个流都没有被使用,才能删除这个指令
  25. for _, out := range typ.OutputStreams().Slots.RawArray() {
  26. if out.Dst.Len() > 0 {
  27. return true
  28. }
  29. }
  30. typ.RemoveAllStream()
  31. ctx.DAG.RemoveNode(typ)
  32. changed = true
  33. return true
  34. })
  35. return changed
  36. }
  37. // 如果Split的结果被完全用于Join,则省略Split和Join指令
  38. func OmitSplitJoin(ctx *state.GenerateState) bool {
  39. changed := false
  40. dag.WalkOnlyType[*ops2.ChunkedSplitNode](ctx.DAG.Graph, func(splitNode *ops2.ChunkedSplitNode) bool {
  41. // Split指令的每一个输出都有且只有一个目的地
  42. var dstNode dag.Node
  43. for _, out := range splitNode.OutputStreams().Slots.RawArray() {
  44. if out.Dst.Len() != 1 {
  45. return true
  46. }
  47. if dstNode == nil {
  48. dstNode = out.Dst.Get(0)
  49. } else if dstNode != out.Dst.Get(0) {
  50. return true
  51. }
  52. }
  53. if dstNode == nil {
  54. return true
  55. }
  56. // 且这个目的地要是一个Join指令
  57. joinNode, ok := dstNode.(*ops2.ChunkedJoinNode)
  58. if !ok {
  59. return true
  60. }
  61. // 同时这个Join指令的输入也必须全部来自Split指令的输出。
  62. // 由于上面判断了Split指令的输出目的地都相同,所以这里只要判断Join指令的输入数量是否与Split指令的输出数量相同即可
  63. if joinNode.InputStreams().Len() != splitNode.OutputStreams().Len() {
  64. return true
  65. }
  66. // 所有条件都满足,可以开始省略操作,将Join操作的目的地的输入流替换为Split操作的输入流:
  67. // F->Split->Join->T 变换为:F->T
  68. splitInput := splitNode.InputStreams().Get(0)
  69. for _, to := range joinNode.Joined().Dst.RawArray() {
  70. splitInput.To(to, to.InputStreams().IndexOf(joinNode.Joined()))
  71. }
  72. splitInput.NotTo(splitNode)
  73. // 并删除这两个指令
  74. ctx.DAG.RemoveNode(joinNode)
  75. ctx.DAG.RemoveNode(splitNode)
  76. changed = true
  77. return true
  78. })
  79. return changed
  80. }

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