in oss/filelike.go [441:497]
func (f *ReadOnlyFile) prefetch(offset int64, _ /*needAtLeast*/ int) (err error) {
off := offset
for _, ar := range f.asyncReaders {
off = ar.oriHttpRange.Offset + ar.oriHttpRange.Count
}
//fmt.Printf("prefetch:offset %v, needAtLeast:%v, off:%v\n", offset, needAtLeast, off)
for len(f.asyncReaders) < f.prefetchNum {
remaining := f.sizeInBytes - off
size := minInt64(remaining, f.chunkSize)
cnt := (size + (AsyncReadeBufferSize - 1)) / AsyncReadeBufferSize
//fmt.Printf("f.sizeInBytes:%v, off:%v, size:%v, cnt:%v\n", f.sizeInBytes, off, size, cnt)
//NewAsyncRangeReader support softStartInitial, add more buffer count to prevent connections from not being released
if size > softStartInitial {
acnt := (AsyncReadeBufferSize+(softStartInitial-1))/softStartInitial - 1
cnt += int64(acnt)
}
if size != 0 {
getFn := func(ctx context.Context, httpRange HTTPRange) (output *ReaderRangeGetOutput, err error) {
request := &GetObjectRequest{
Bucket: Ptr(f.bucket),
Key: Ptr(f.key),
VersionId: f.versionId,
RequestPayer: f.requestPayer,
}
rangeStr := httpRange.FormatHTTPRange()
if rangeStr != nil {
request.Range = rangeStr
request.RangeBehavior = Ptr("standard")
}
var result *GetObjectResult
result, err = f.client.GetObject(f.context, request)
if err != nil {
return nil, err
}
return &ReaderRangeGetOutput{
Body: result.Body,
ETag: result.ETag,
ContentLength: result.ContentLength,
ContentRange: result.ContentRange,
}, nil
//fmt.Printf("result.Headers:%#v\n", result.Headers)
}
ar, err := NewAsyncRangeReader(f.context, getFn, &HTTPRange{off, size}, f.etag, int(cnt))
if err != nil {
break
}
f.asyncReaders = append(f.asyncReaders, ar)
off += size
}
if size != f.chunkSize {
break
}
}
return nil
}