github.com/qjfoidnh/BaiduPCS-Go@v0.0.0-20231011165705-caa18a3765f3/requester/transfer/rangelist.go (about)

     1  package transfer
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"github.com/qjfoidnh/BaiduPCS-Go/pcsutil/converter"
     7  	"sync"
     8  	"sync/atomic"
     9  )
    10  
    11  type (
    12  	//RangeList 请求范围列表
    13  	RangeList []*Range
    14  
    15  	//RangeListGen Range 生成器
    16  	RangeListGen struct {
    17  		total        int64
    18  		begin        int64
    19  		blockSize    int64
    20  		parallel     int
    21  		count        int // 已生成次数
    22  		rangeGenMode RangeGenMode
    23  		mu           sync.Mutex
    24  	}
    25  )
    26  
    27  const (
    28  	// DefaultBlockSize 默认的BlockSize
    29  	DefaultBlockSize = 256 * converter.KB
    30  )
    31  
    32  var (
    33  	// ErrUnknownRangeGenMode RangeGenMode 非法
    34  	ErrUnknownRangeGenMode = errors.New("Unknown RangeGenMode")
    35  )
    36  
    37  //Len 长度
    38  func (r *Range) Len() int64 {
    39  	return r.LoadEnd() - r.LoadBegin()
    40  }
    41  
    42  //LoadBegin 读取Begin, 原子操作
    43  func (r *Range) LoadBegin() int64 {
    44  	return atomic.LoadInt64(&r.Begin)
    45  }
    46  
    47  //AddBegin 增加Begin, 原子操作
    48  func (r *Range) AddBegin(i int64) (newi int64) {
    49  	return atomic.AddInt64(&r.Begin, i)
    50  }
    51  
    52  //LoadEnd 读取End, 原子操作
    53  func (r *Range) LoadEnd() int64 {
    54  	return atomic.LoadInt64(&r.End)
    55  }
    56  
    57  //StoreBegin 储存End, 原子操作
    58  func (r *Range) StoreBegin(end int64) {
    59  	atomic.StoreInt64(&r.Begin, end)
    60  }
    61  
    62  //StoreEnd 储存End, 原子操作
    63  func (r *Range) StoreEnd(end int64) {
    64  	atomic.StoreInt64(&r.End, end)
    65  }
    66  
    67  // ShowDetails 显示Range细节
    68  func (r *Range) ShowDetails() string {
    69  	return fmt.Sprintf("{%d-%d}", r.LoadBegin(), r.LoadEnd())
    70  }
    71  
    72  //Len 获取所有的Range的剩余长度
    73  func (rl *RangeList) Len() int64 {
    74  	var l int64
    75  	for _, wrange := range *rl {
    76  		if wrange == nil {
    77  			continue
    78  		}
    79  		l += wrange.Len()
    80  	}
    81  	return l
    82  }
    83  
    84  // NewRangeListGenDefault 初始化默认Range生成器, 根据parallel平均生成
    85  func NewRangeListGenDefault(totalSize, begin int64, count, parallel int) *RangeListGen {
    86  	return &RangeListGen{
    87  		total:        totalSize,
    88  		begin:        begin,
    89  		parallel:     parallel,
    90  		count:        count,
    91  		rangeGenMode: RangeGenMode_Default,
    92  	}
    93  }
    94  
    95  // NewRangeListGenBlockSize 初始化Range生成器, 根据blockSize生成
    96  func NewRangeListGenBlockSize(totalSize, begin, blockSize int64) *RangeListGen {
    97  	return &RangeListGen{
    98  		total:        totalSize,
    99  		begin:        begin,
   100  		blockSize:    blockSize,
   101  		rangeGenMode: RangeGenMode_BlockSize,
   102  	}
   103  }
   104  
   105  // RangeGenMode 返回Range生成方式
   106  func (gen *RangeListGen) RangeGenMode() RangeGenMode {
   107  	return gen.rangeGenMode
   108  }
   109  
   110  // RangeCount 返回预计生成的Range数量
   111  func (gen *RangeListGen) RangeCount() (rangeCount int) {
   112  	switch gen.rangeGenMode {
   113  	case RangeGenMode_Default:
   114  		rangeCount = gen.parallel - gen.count
   115  		//rangeCount = int(math.Ceil(float64(gen.total) / float64(gen.blockSize)))
   116  	case RangeGenMode_BlockSize:
   117  		rangeCount = int((gen.total - gen.begin) / gen.blockSize)
   118  		if gen.total%gen.blockSize != 0 {
   119  			rangeCount++
   120  		}
   121  	}
   122  	return
   123  }
   124  
   125  // LoadBegin 返回begin
   126  func (gen *RangeListGen) LoadBegin() (begin int64) {
   127  	gen.mu.Lock()
   128  	begin = gen.begin
   129  	gen.mu.Unlock()
   130  	return
   131  }
   132  
   133  // LoadBlockSize 返回blockSize
   134  func (gen *RangeListGen) LoadBlockSize() (blockSize int64) {
   135  	switch gen.rangeGenMode {
   136  	case RangeGenMode_Default:
   137  		if gen.blockSize <= 0 {
   138  			gen.blockSize = (gen.total - gen.begin) / int64(gen.parallel)
   139  			if gen.blockSize < 256 * converter.KB {
   140  				gen.blockSize = 256 * converter.KB
   141  			}
   142  		}
   143  		blockSize = gen.blockSize
   144  	case RangeGenMode_BlockSize:
   145  		blockSize = gen.blockSize
   146  	}
   147  	return
   148  }
   149  
   150  // IsDone 是否已分配完成
   151  func (gen *RangeListGen) IsDone() bool {
   152  	return gen.begin >= gen.total
   153  }
   154  
   155  // GenRange 生成 Range
   156  func (gen *RangeListGen) GenRange() (index int, r *Range) {
   157  	var (
   158  		end int64
   159  	)
   160  	if gen.parallel < 1 {
   161  		gen.parallel = 1
   162  	}
   163  	switch gen.rangeGenMode {
   164  	case RangeGenMode_Default:
   165  		gen.LoadBlockSize()
   166  		gen.mu.Lock()
   167  		defer gen.mu.Unlock()
   168  
   169  		if gen.IsDone() {
   170  			return gen.count, nil
   171  		}
   172  
   173  		gen.count++
   174  		if gen.count >= gen.parallel {
   175  			end = gen.total
   176  		} else {
   177  			end = gen.begin + gen.blockSize
   178  		}
   179  
   180  		//end = gen.begin + gen.blockSize
   181  		if end >= gen.total {
   182  			end = gen.total
   183  		}
   184  
   185  		r = &Range{
   186  			Begin: gen.begin,
   187  			End:   end,
   188  		}
   189  
   190  		gen.begin = end
   191  		index = gen.count - 1
   192  		return
   193  	case RangeGenMode_BlockSize:
   194  		if gen.blockSize <= 0 {
   195  			gen.blockSize = DefaultBlockSize
   196  		}
   197  		gen.mu.Lock()
   198  		defer gen.mu.Unlock()
   199  
   200  		if gen.IsDone() {
   201  			return gen.count, nil
   202  		}
   203  
   204  		gen.count++
   205  		end = gen.begin + gen.blockSize
   206  		if end >= gen.total {
   207  			end = gen.total
   208  		}
   209  		r = &Range{
   210  			Begin: gen.begin,
   211  			End:   end,
   212  		}
   213  		gen.begin = end
   214  		index = gen.count - 1
   215  		return
   216  	}
   217  
   218  	return 0, nil
   219  }