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.4 kB

7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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/jcs-pub/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].UserSpace.Storage.String()))
  18. }
  19. logger.Debug(logStrs...)
  20. length := req.Detail.Object.Size - req.Raw.Offset
  21. if req.Raw.Length != -1 {
  22. length = req.Raw.Length
  23. }
  24. shouldAtClient := iter.downloader.speedStats.ShouldAtClient(length)
  25. downloadBlks := make([]downloadBlock, len(strg.Blocks))
  26. for i, b := range strg.Blocks {
  27. fromSpace := strg.Spaces[i]
  28. if shouldAtClient {
  29. fromSpace.RecommendHub = nil
  30. }
  31. downloadBlks[i] = downloadBlock{
  32. Block: b,
  33. Space: fromSpace,
  34. }
  35. }
  36. pr, pw := io.Pipe()
  37. go func() {
  38. readPos := req.Raw.Offset
  39. totalReadLen := req.Detail.Object.Size - req.Raw.Offset
  40. if req.Raw.Length >= 0 {
  41. totalReadLen = math2.Min(req.Raw.Length, totalReadLen)
  42. }
  43. firstStripIndex := readPos / int64(strg.Redundancy.K) / int64(strg.Redundancy.ChunkSize)
  44. stripIter := NewLRCStripIterator(iter.downloader, req.Detail.Object, downloadBlks, strg.Redundancy, firstStripIndex, iter.downloader.strips, iter.downloader.cfg.ECStripPrefetchCount)
  45. defer stripIter.Close()
  46. for totalReadLen > 0 {
  47. strip, err := stripIter.MoveNext()
  48. if err == iterator.ErrNoMoreItem {
  49. pw.CloseWithError(io.ErrUnexpectedEOF)
  50. return
  51. }
  52. if err != nil {
  53. pw.CloseWithError(err)
  54. return
  55. }
  56. readRelativePos := readPos - strip.Position
  57. nextStripPos := strip.Position + int64(strg.Redundancy.K)*int64(strg.Redundancy.ChunkSize)
  58. curReadLen := math2.Min(totalReadLen, nextStripPos-readPos)
  59. err = io2.WriteAll(pw, strip.Data[readRelativePos:readRelativePos+curReadLen])
  60. if err != nil {
  61. pw.CloseWithError(err)
  62. return
  63. }
  64. totalReadLen -= curReadLen
  65. readPos += curReadLen
  66. }
  67. pw.Close()
  68. }()
  69. return pr, nil
  70. }

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