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.

misc.go 4.7 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package opt
  2. import (
  3. "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag"
  4. "gitlink.org.cn/cloudream/common/utils/math2"
  5. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/ops2"
  6. "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch2/parser/state"
  7. )
  8. // 删除未使用的BaseRead指令,如果是FromNode则会一并从FromNodes中删除。
  9. // 对于BaseReadDyn指令,如果它的上级是GetShardInfo,且只有一个输出,则会一并删除这个节点
  10. func RemoveUnusedBaseRead(ctx *state.GenerateState) {
  11. dag.WalkOnlyType[*ops2.BaseReadNode](ctx.DAG.Graph, func(node *ops2.BaseReadNode) bool {
  12. if node.Output().Var().Dst.Len() == 0 {
  13. ctx.DAG.RemoveNode(node)
  14. }
  15. return true
  16. })
  17. dag.WalkOnlyType[*ops2.BaseReadDynNode](ctx.DAG.Graph, func(node *ops2.BaseReadDynNode) bool {
  18. if node.Output().Var().Dst.Len() == 0 {
  19. ctx.DAG.RemoveNode(node)
  20. srcVar := node.FileInfoSlot().Var()
  21. if srcVar == nil {
  22. return true
  23. }
  24. srcVar.NotTo(node)
  25. // 暂时限定只处理GetShardInfo
  26. _, ok := srcVar.Src.(*ops2.GetShardInfoNode)
  27. if !ok {
  28. return true
  29. }
  30. if srcVar.Dst.Len() == 0 {
  31. ctx.DAG.RemoveNode(srcVar.Src)
  32. }
  33. }
  34. return true
  35. })
  36. }
  37. // 对于所有未使用的流,增加Drop指令
  38. func DropUnused(ctx *state.GenerateState) {
  39. ctx.DAG.Walk(func(node dag.Node) bool {
  40. for _, out := range node.OutputStreams().Slots.RawArray() {
  41. if out.Dst.Len() == 0 {
  42. n := ctx.DAG.NewDropStream()
  43. *n.Env() = *node.Env()
  44. n.SetInput(out)
  45. }
  46. }
  47. return true
  48. })
  49. }
  50. // 为IPFS写入指令存储结果
  51. func StoreShardWriteResult(ctx *state.GenerateState) {
  52. dag.WalkOnlyType[*ops2.StoreShardNode](ctx.DAG.Graph, func(n *ops2.StoreShardNode) bool {
  53. if n.ShardInfoKey == "" {
  54. return true
  55. }
  56. storeNode := ctx.DAG.NewStore()
  57. storeNode.Env().ToEnvDriver(true)
  58. storeNode.Store(n.ShardInfoKey, n.ShardInfoVar().Var())
  59. return true
  60. })
  61. }
  62. // 生成Range指令。StreamRange可能超过文件总大小,但Range指令会在数据量不够时不报错而是正常返回
  63. func GenerateRange(ctx *state.GenerateState) {
  64. dag.WalkOnlyType[ops2.ToNode](ctx.DAG.Graph, func(toNode ops2.ToNode) bool {
  65. to := toNode.GetTo()
  66. toStrIdx := to.GetStreamIndex()
  67. toRng := to.GetRange()
  68. if toStrIdx.IsRaw() {
  69. n := ctx.DAG.NewRange()
  70. toInput := toNode.Input()
  71. *n.Env() = *toInput.Var().Src.Env()
  72. rnged := n.RangeStream(toInput.Var(), math2.Range{
  73. Offset: toRng.Offset - ctx.StreamRange.Offset,
  74. Length: toRng.Length,
  75. })
  76. toInput.Var().NotTo(toNode)
  77. rnged.ToSlot(toInput)
  78. } else if toStrIdx.IsEC() {
  79. stripSize := int64(ctx.Ft.ECParam.ChunkSize * ctx.Ft.ECParam.K)
  80. blkStartIdx := ctx.StreamRange.Offset / stripSize
  81. blkStart := blkStartIdx * int64(ctx.Ft.ECParam.ChunkSize)
  82. n := ctx.DAG.NewRange()
  83. toInput := toNode.Input()
  84. *n.Env() = *toInput.Var().Src.Env()
  85. rnged := n.RangeStream(toInput.Var(), math2.Range{
  86. Offset: toRng.Offset - blkStart,
  87. Length: toRng.Length,
  88. })
  89. toInput.Var().NotTo(toNode)
  90. rnged.ToSlot(toInput)
  91. } else if toStrIdx.IsSegment() {
  92. // if frNode, ok := toNode.Input().Var().From().Node.(ops2.FromNode); ok {
  93. // // 目前只有To也是分段时,才可能对接一个提供分段的From,此时不需要再生成Range指令
  94. // if frNode.GetFrom().GetStreamIndex().IsSegment() {
  95. // continue
  96. // }
  97. // }
  98. // segStart := ctx.Ft.SegmentParam.CalcSegmentStart(toStrIdx.Index)
  99. // strStart := segStart + toRng.Offset
  100. // n := ctx.DAG.NewRange()
  101. // toInput := toNode.Input()
  102. // *n.Env() = *toInput.Var().From().Node.Env()
  103. // rnged := n.RangeStream(toInput.Var(), exec.Range{
  104. // Offset: strStart - ctx.StreamRange.Offset,
  105. // Length: toRng.Length,
  106. // })
  107. // toInput.Var().NotTo(toNode, toInput.Index)
  108. // toNode.SetInput(rnged)
  109. }
  110. return true
  111. })
  112. }
  113. // 生成Clone指令
  114. func GenerateClone(ctx *state.GenerateState) {
  115. ctx.DAG.Walk(func(node dag.Node) bool {
  116. for _, outVar := range node.OutputStreams().Slots.RawArray() {
  117. if outVar.Dst.Len() <= 1 {
  118. continue
  119. }
  120. c := ctx.DAG.NewCloneStream()
  121. *c.Env() = *node.Env()
  122. for _, dst := range outVar.Dst.RawArray() {
  123. c.NewOutput().To(dst, dst.InputStreams().IndexOf(outVar))
  124. }
  125. outVar.Dst.Resize(0)
  126. c.SetInput(outVar)
  127. }
  128. for _, outVar := range node.OutputValues().Slots.RawArray() {
  129. if outVar.Dst.Len() <= 1 {
  130. continue
  131. }
  132. t := ctx.DAG.NewCloneValue()
  133. *t.Env() = *node.Env()
  134. for _, dst := range outVar.Dst.RawArray() {
  135. t.NewOutput().To(dst, dst.InputValues().IndexOf(outVar))
  136. }
  137. outVar.Dst.Resize(0)
  138. t.SetInput(outVar)
  139. }
  140. return true
  141. })
  142. }

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