github.com/iikira/iikira-go-utils@v0.0.0-20230610031953-f2cb11cde33a/requester/transfer/download_status.go (about)

     1  package transfer
     2  
     3  import (
     4  	"github.com/iikira/iikira-go-utils/requester/rio/speeds"
     5  	"sync"
     6  	"sync/atomic"
     7  	"time"
     8  )
     9  
    10  type (
    11  	//DownloadStatuser 下载状态接口
    12  	DownloadStatuser interface {
    13  		TotalSize() int64
    14  		Downloaded() int64
    15  		SpeedsPerSecond() int64
    16  		TimeElapsed() time.Duration // 已开始时间
    17  		TimeLeft() time.Duration    // 预计剩余时间, 负数代表未知
    18  	}
    19  
    20  	//DownloadStatus 下载状态及统计信息
    21  	DownloadStatus struct {
    22  		totalSize        int64          // 总大小
    23  		downloaded       int64          // 已下载的数据量
    24  		speedsDownloaded int64          // 用于统计速度的downloaded
    25  		maxSpeeds        int64          // 最大下载速度
    26  		tmpSpeeds        int64          // 缓存的速度
    27  		speedsStat       speeds.Speeds // 速度统计 (注意对齐)
    28  
    29  		startTime time.Time // 开始下载的时间
    30  
    31  		rateLimit *speeds.RateLimit // 限速控制
    32  
    33  		gen *RangeListGen // Range生成状态
    34  		mu  sync.Mutex
    35  	}
    36  )
    37  
    38  //NewDownloadStatus 初始化DownloadStatus
    39  func NewDownloadStatus() *DownloadStatus {
    40  	return &DownloadStatus{
    41  		startTime: time.Now(),
    42  	}
    43  }
    44  
    45  // SetRateLimit 设置限速
    46  func (ds *DownloadStatus) SetRateLimit(rl *speeds.RateLimit) {
    47  	ds.rateLimit = rl
    48  }
    49  
    50  //SetTotalSize 返回总大小
    51  func (ds *DownloadStatus) SetTotalSize(size int64) {
    52  	ds.totalSize = size
    53  }
    54  
    55  //AddDownloaded 增加已下载数据量
    56  func (ds *DownloadStatus) AddDownloaded(d int64) {
    57  	atomic.AddInt64(&ds.downloaded, d)
    58  }
    59  
    60  //AddTotalSize 增加总大小 (不支持多线程)
    61  func (ds *DownloadStatus) AddTotalSize(size int64) {
    62  	ds.totalSize += size
    63  }
    64  
    65  //AddSpeedsDownloaded 增加已下载数据量, 用于统计速度
    66  func (ds *DownloadStatus) AddSpeedsDownloaded(d int64) {
    67  	if ds.rateLimit != nil {
    68  		ds.rateLimit.Add(d)
    69  	}
    70  	ds.speedsStat.Add(d)
    71  }
    72  
    73  //SetMaxSpeeds 设置最大速度, 原子操作
    74  func (ds *DownloadStatus) SetMaxSpeeds(speeds int64) {
    75  	if speeds > atomic.LoadInt64(&ds.maxSpeeds) {
    76  		atomic.StoreInt64(&ds.maxSpeeds, speeds)
    77  	}
    78  }
    79  
    80  //ClearMaxSpeeds 清空统计最大速度, 原子操作
    81  func (ds *DownloadStatus) ClearMaxSpeeds() {
    82  	atomic.StoreInt64(&ds.maxSpeeds, 0)
    83  }
    84  
    85  //TotalSize 返回总大小
    86  func (ds *DownloadStatus) TotalSize() int64 {
    87  	return ds.totalSize
    88  }
    89  
    90  //Downloaded 返回已下载数据量
    91  func (ds *DownloadStatus) Downloaded() int64 {
    92  	return atomic.LoadInt64(&ds.downloaded)
    93  }
    94  
    95  // UpdateSpeeds 更新speeds
    96  func (ds *DownloadStatus) UpdateSpeeds() {
    97  	atomic.StoreInt64(&ds.tmpSpeeds, ds.speedsStat.GetSpeeds())
    98  }
    99  
   100  //SpeedsPerSecond 返回每秒速度
   101  func (ds *DownloadStatus) SpeedsPerSecond() int64 {
   102  	return atomic.LoadInt64(&ds.tmpSpeeds)
   103  }
   104  
   105  //MaxSpeeds 返回最大速度
   106  func (ds *DownloadStatus) MaxSpeeds() int64 {
   107  	return atomic.LoadInt64(&ds.maxSpeeds)
   108  }
   109  
   110  //TimeElapsed 返回花费的时间
   111  func (ds *DownloadStatus) TimeElapsed() (elapsed time.Duration) {
   112  	return time.Since(ds.startTime)
   113  }
   114  
   115  //TimeLeft 返回预计剩余时间
   116  func (ds *DownloadStatus) TimeLeft() (left time.Duration) {
   117  	speeds := atomic.LoadInt64(&ds.tmpSpeeds)
   118  	if speeds <= 0 {
   119  		left = -1
   120  	} else {
   121  		left = time.Duration((ds.totalSize-ds.downloaded)/(speeds)) * time.Second
   122  	}
   123  	return
   124  }
   125  
   126  // RangeListGen 返回RangeListGen
   127  func (ds *DownloadStatus) RangeListGen() *RangeListGen {
   128  	return ds.gen
   129  }
   130  
   131  // SetRangeListGen 设置RangeListGen
   132  func (ds *DownloadStatus) SetRangeListGen(gen *RangeListGen) {
   133  	ds.gen = gen
   134  }