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_multiplier.go 2.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package efile
  2. import (
  3. "fmt"
  4. "net/http"
  5. "net/url"
  6. "path"
  7. "gitlink.org.cn/cloudream/common/utils/http2"
  8. "gitlink.org.cn/cloudream/common/utils/os2"
  9. "gitlink.org.cn/cloudream/common/utils/serder"
  10. stgtypes "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
  11. jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types"
  12. )
  13. type ECMultiplier struct {
  14. blder *builder
  15. url string
  16. feat *jcstypes.ECMultiplierFeature
  17. outputs []string
  18. }
  19. // 进行EC运算,coef * inputs。coef为编码矩阵,inputs为待编码数据,chunkSize为分块大小。
  20. // 输出为每一个块文件的路径,数组长度 = len(coef)
  21. func (m *ECMultiplier) Multiply(coef [][]byte, inputs []stgtypes.HTTPRequest, chunkSize int) ([]stgtypes.FileInfo, error) {
  22. type Request struct {
  23. Inputs []stgtypes.HTTPRequest `json:"inputs"`
  24. Outputs []string `json:"outputs"`
  25. Coefs [][]int `json:"coefs"` // 用int防止被base64编码
  26. ChunkSize int `json:"chunkSize"`
  27. }
  28. type Response struct {
  29. Code string `json:"code"`
  30. Msg string `json:"msg"`
  31. Data []struct {
  32. Size int64 `json:"size"`
  33. Sha256 string `json:"sha256"`
  34. }
  35. }
  36. intCoefs := make([][]int, len(coef))
  37. for i := range intCoefs {
  38. intCoefs[i] = make([]int, len(coef[i]))
  39. for j := range intCoefs[i] {
  40. intCoefs[i][j] = int(coef[i][j])
  41. }
  42. }
  43. fileName := os2.GenerateRandomFileName(10)
  44. tempDir := path.Join(m.blder.detail.UserSpace.WorkingDir.String(), stgtypes.TempWorkingDir)
  45. m.outputs = make([]string, len(coef))
  46. for i := range m.outputs {
  47. m.outputs[i] = path.Join(tempDir, fmt.Sprintf("%s_%d", fileName, i))
  48. }
  49. u, err := url.JoinPath(m.url, "efile/openapi/v2/file/createECTask")
  50. if err != nil {
  51. return nil, err
  52. }
  53. token, err := m.blder.getToken()
  54. if err != nil {
  55. return nil, fmt.Errorf("get token: %w", err)
  56. }
  57. resp, err := http2.PostJSON(u, http2.RequestParam{
  58. Header: map[string]string{"token": token},
  59. Body: Request{
  60. Inputs: inputs,
  61. Outputs: m.outputs,
  62. Coefs: intCoefs,
  63. ChunkSize: chunkSize,
  64. },
  65. })
  66. if err != nil {
  67. return nil, err
  68. }
  69. if resp.StatusCode != http.StatusOK {
  70. return nil, fmt.Errorf("status code: %d", resp.StatusCode)
  71. }
  72. var r Response
  73. err = serder.JSONToObjectStream(resp.Body, &r)
  74. if err != nil {
  75. return nil, err
  76. }
  77. if r.Code != "0" {
  78. return nil, fmt.Errorf("code: %s, msg: %s", r.Code, r.Msg)
  79. }
  80. if len(r.Data) != len(m.outputs) {
  81. return nil, fmt.Errorf("data length not match outputs length")
  82. }
  83. ret := make([]stgtypes.FileInfo, len(r.Data))
  84. for i, data := range r.Data {
  85. ret[i] = stgtypes.FileInfo{
  86. // TODO 要确认一下output的格式
  87. Path: jcstypes.PathFromJcsPathString(m.outputs[i]),
  88. Size: data.Size,
  89. Hash: jcstypes.NewFullHashFromString(data.Sha256),
  90. }
  91. }
  92. return ret, nil
  93. }
  94. func (m *ECMultiplier) Close() {}

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