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 2.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package ops
  2. import (
  3. "fmt"
  4. "io"
  5. "sync"
  6. cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
  7. myio "gitlink.org.cn/cloudream/common/utils/io"
  8. "gitlink.org.cn/cloudream/storage/common/pkgs/ec"
  9. "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch"
  10. )
  11. type ECReconstructAny struct {
  12. EC cdssdk.ECRedundancy `json:"ec"`
  13. InputIDs []ioswitch.StreamID `json:"inputIDs"`
  14. OutputIDs []ioswitch.StreamID `json:"outputIDs"`
  15. InputBlockIndexes []int `json:"inputBlockIndexes"`
  16. OutputBlockIndexes []int `json:"outputBlockIndexes"`
  17. }
  18. func (o *ECReconstructAny) Execute(sw *ioswitch.Switch, planID ioswitch.PlanID) error {
  19. rs, err := ec.NewRs(o.EC.K, o.EC.N, o.EC.ChunkSize)
  20. if err != nil {
  21. return fmt.Errorf("new ec: %w", err)
  22. }
  23. strs, err := sw.WaitStreams(planID, o.InputIDs...)
  24. if err != nil {
  25. return err
  26. }
  27. defer func() {
  28. for _, s := range strs {
  29. s.Stream.Close()
  30. }
  31. }()
  32. var inputs []io.Reader
  33. for _, s := range strs {
  34. inputs = append(inputs, s.Stream)
  35. }
  36. outputs := rs.ReconstructAny(inputs, o.InputBlockIndexes, o.OutputBlockIndexes)
  37. wg := sync.WaitGroup{}
  38. for i, id := range o.OutputIDs {
  39. wg.Add(1)
  40. sw.StreamReady(planID, ioswitch.NewStream(id, myio.AfterReadClosedOnce(outputs[i], func(closer io.ReadCloser) {
  41. wg.Done()
  42. })))
  43. }
  44. wg.Wait()
  45. return nil
  46. }
  47. type ECReconstruct struct {
  48. EC cdssdk.ECRedundancy `json:"ec"`
  49. InputIDs []ioswitch.StreamID `json:"inputIDs"`
  50. OutputIDs []ioswitch.StreamID `json:"outputIDs"`
  51. InputBlockIndexes []int `json:"inputBlockIndexes"`
  52. }
  53. func (o *ECReconstruct) Execute(sw *ioswitch.Switch, planID ioswitch.PlanID) error {
  54. rs, err := ec.NewRs(o.EC.K, o.EC.N, o.EC.ChunkSize)
  55. if err != nil {
  56. return fmt.Errorf("new ec: %w", err)
  57. }
  58. strs, err := sw.WaitStreams(planID, o.InputIDs...)
  59. if err != nil {
  60. return err
  61. }
  62. defer func() {
  63. for _, s := range strs {
  64. s.Stream.Close()
  65. }
  66. }()
  67. var inputs []io.Reader
  68. for _, s := range strs {
  69. inputs = append(inputs, s.Stream)
  70. }
  71. outputs := rs.ReconstructData(inputs, o.InputBlockIndexes)
  72. wg := sync.WaitGroup{}
  73. for i, id := range o.OutputIDs {
  74. wg.Add(1)
  75. sw.StreamReady(planID, ioswitch.NewStream(id, myio.AfterReadClosedOnce(outputs[i], func(closer io.ReadCloser) {
  76. wg.Done()
  77. })))
  78. }
  79. wg.Wait()
  80. return nil
  81. }
  82. func init() {
  83. OpUnion.AddT((*ECReconstructAny)(nil))
  84. OpUnion.AddT((*ECReconstruct)(nil))
  85. }

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