first commit
This commit is contained in:
53
httpdl/segment.go
Normal file
53
httpdl/segment.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package httpdl
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
// seg is one contiguous byte range of the output file, downloaded by a single
|
||||
// ranged GET. A segment IS a byte range — a plain HTTP downloader does not need
|
||||
// the Piece/Segment/block layering that exists only to share code with
|
||||
// BitTorrent. written is updated with atomic ops so Stat() can read it while a
|
||||
// worker advances it.
|
||||
type seg struct {
|
||||
index int
|
||||
start int64 // first byte offset, inclusive
|
||||
end int64 // last byte offset, inclusive
|
||||
written int64 // bytes already written into this segment (the resume point)
|
||||
}
|
||||
|
||||
func (s *seg) length() int64 { return s.end - s.start + 1 }
|
||||
func (s *seg) done() bool { return atomic.LoadInt64(&s.written) >= s.length() }
|
||||
func (s *seg) advance(n int64) { atomic.AddInt64(&s.written, n) }
|
||||
func (s *seg) progress() int64 { return atomic.LoadInt64(&s.written) }
|
||||
func (s *seg) offset() int64 { return s.start + atomic.LoadInt64(&s.written) }
|
||||
func (s *seg) remaining() int64 { return s.length() - atomic.LoadInt64(&s.written) }
|
||||
|
||||
// makeSegments divides a file of total bytes into contiguous segments, using at
|
||||
// most conns of them and never splitting below minSplit. The remainder lands in
|
||||
// the last segment. With conns==1 (the default) this yields one segment.
|
||||
func makeSegments(total, minSplit int64, conns int) []seg {
|
||||
if conns < 1 {
|
||||
conns = 1
|
||||
}
|
||||
if minSplit < 1 {
|
||||
minSplit = 1
|
||||
}
|
||||
n := int64(conns)
|
||||
if max := total / minSplit; max < n {
|
||||
n = max
|
||||
}
|
||||
if n < 1 {
|
||||
n = 1
|
||||
}
|
||||
chunk := total / n
|
||||
segs := make([]seg, n)
|
||||
var start int64
|
||||
for i := int64(0); i < n; i++ {
|
||||
end := start + chunk - 1
|
||||
if i == n-1 {
|
||||
end = total - 1
|
||||
}
|
||||
segs[i] = seg{index: int(i), start: start, end: end}
|
||||
start = end + 1
|
||||
}
|
||||
return segs
|
||||
}
|
||||
Reference in New Issue
Block a user