func()

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
}