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.

lrc.go 2.1 kB

7 months ago
7 months ago
7 months ago
7 months ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package downloader
  2. import (
  3. "fmt"
  4. "io"
  5. "gitlink.org.cn/cloudream/common/pkgs/iterator"
  6. "gitlink.org.cn/cloudream/common/pkgs/logger"
  7. "gitlink.org.cn/cloudream/common/utils/io2"
  8. "gitlink.org.cn/cloudream/common/utils/math2"
  9. "gitlink.org.cn/cloudream/storage2/client/internal/downloader/strategy"
  10. )
  11. func (iter *DownloadObjectIterator) downloadLRCReconstruct(req downloadReqeust2, strg strategy.LRCReconstructStrategy) (io.ReadCloser, error) {
  12. var logStrs []any = []any{fmt.Sprintf("downloading lrc object %v from: ", req.Raw.ObjectID)}
  13. for i, b := range strg.Blocks {
  14. if i > 0 {
  15. logStrs = append(logStrs, ", ")
  16. }
  17. logStrs = append(logStrs, fmt.Sprintf("%v@%v", b.Index, strg.Spaces[i].Storage.String()))
  18. }
  19. logger.Debug(logStrs...)
  20. downloadBlks := make([]downloadBlock, len(strg.Blocks))
  21. for i, b := range strg.Blocks {
  22. downloadBlks[i] = downloadBlock{
  23. Block: b,
  24. Space: strg.Spaces[i],
  25. }
  26. }
  27. pr, pw := io.Pipe()
  28. go func() {
  29. readPos := req.Raw.Offset
  30. totalReadLen := req.Detail.Object.Size - req.Raw.Offset
  31. if req.Raw.Length >= 0 {
  32. totalReadLen = math2.Min(req.Raw.Length, totalReadLen)
  33. }
  34. firstStripIndex := readPos / int64(strg.Redundancy.K) / int64(strg.Redundancy.ChunkSize)
  35. stripIter := NewLRCStripIterator(iter.downloader, req.Detail.Object, downloadBlks, strg.Redundancy, firstStripIndex, iter.downloader.strips, iter.downloader.cfg.ECStripPrefetchCount)
  36. defer stripIter.Close()
  37. for totalReadLen > 0 {
  38. strip, err := stripIter.MoveNext()
  39. if err == iterator.ErrNoMoreItem {
  40. pw.CloseWithError(io.ErrUnexpectedEOF)
  41. return
  42. }
  43. if err != nil {
  44. pw.CloseWithError(err)
  45. return
  46. }
  47. readRelativePos := readPos - strip.Position
  48. nextStripPos := strip.Position + int64(strg.Redundancy.K)*int64(strg.Redundancy.ChunkSize)
  49. curReadLen := math2.Min(totalReadLen, nextStripPos-readPos)
  50. err = io2.WriteAll(pw, strip.Data[readRelativePos:readRelativePos+curReadLen])
  51. if err != nil {
  52. pw.CloseWithError(err)
  53. return
  54. }
  55. totalReadLen -= curReadLen
  56. readPos += curReadLen
  57. }
  58. pw.Close()
  59. }()
  60. return pr, nil
  61. }

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