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.

remote.go 1.9 kB

8 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package cache
  2. import (
  3. "io"
  4. "time"
  5. )
  6. type RemoteLoader struct {
  7. file *CacheFile
  8. loaders []*OpenLoader
  9. }
  10. type OpenLoader struct {
  11. reader io.ReadCloser
  12. pos int64
  13. lastUsedTime time.Time
  14. }
  15. func newRemoteLoader(file *CacheFile) *RemoteLoader {
  16. return &RemoteLoader{
  17. file: file,
  18. loaders: make([]*OpenLoader, 2),
  19. }
  20. }
  21. func (r *RemoteLoader) Load(p []byte, pos int64) (n int, err error) {
  22. replaceIdx := -1
  23. for i := 0; i < len(r.loaders); i++ {
  24. loader := r.loaders[i]
  25. if loader == nil {
  26. replaceIdx = i
  27. continue
  28. }
  29. // 找到一个position刚好等于off的loader
  30. if loader.pos == pos {
  31. loader.lastUsedTime = time.Now()
  32. n, err = io.ReadFull(loader.reader, p)
  33. loader.pos += int64(n)
  34. if err != nil {
  35. loader.reader.Close()
  36. r.loaders[i] = nil
  37. }
  38. return
  39. }
  40. if replaceIdx == -1 || r.loaders[replaceIdx] != nil && r.loaders[replaceIdx].lastUsedTime.After(loader.lastUsedTime) {
  41. replaceIdx = i
  42. }
  43. }
  44. if r.loaders[replaceIdx] != nil {
  45. r.loaders[replaceIdx].reader.Close()
  46. r.loaders[replaceIdx] = nil
  47. }
  48. loader, err := r.newLoader(pos)
  49. if err != nil {
  50. return 0, err
  51. }
  52. loader.lastUsedTime = time.Now()
  53. r.loaders[replaceIdx] = loader
  54. n, err = io.ReadFull(loader.reader, p)
  55. loader.pos += int64(n)
  56. if err != nil {
  57. loader.reader.Close()
  58. r.loaders[replaceIdx] = nil
  59. }
  60. return
  61. }
  62. func (r *RemoteLoader) Close() {
  63. for i := 0; i < len(r.loaders); i++ {
  64. if r.loaders[i] != nil {
  65. r.loaders[i].reader.Close()
  66. }
  67. }
  68. }
  69. func (r *RemoteLoader) newLoader(pos int64) (*OpenLoader, error) {
  70. detail, err := r.file.cache.db.Object().GetDetail(r.file.cache.db.DefCtx(), r.file.remoteObj.ObjectID)
  71. if err != nil {
  72. return nil, err
  73. }
  74. down, err := r.file.cache.downloader.DownloadObjectByDetail(detail, pos, -1)
  75. if err != nil {
  76. return nil, err
  77. }
  78. return &OpenLoader{
  79. reader: down.File,
  80. pos: pos,
  81. }, nil
  82. }

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