in pkg/files/store/file.go [112:144]
func (f *file) ReadAt(buff []byte, offset int64) (int, error) {
fileSize, err := f.Fstat()
if err != nil {
return 0, err
}
alignedOffset := math.AlignDown(offset, int64(files.CacheBlockSize))
if f.chunkOffset != 0 && alignedOffset != f.chunkOffset {
f.reader.Log().Error().Err(errOnlySingleChunkAvailable).Int64("chunk", f.chunkOffset).Int64("alignedOffset", alignedOffset).Int64("requestedOffset", offset).Msg("file can only read chunk")
return -1, errOnlySingleChunkAvailable
}
count := int(math.Min64(int64(files.CacheBlockSize), fileSize-alignedOffset))
data, err := f.store.cache.GetOrCreate(f.Name, alignedOffset, count, func() ([]byte, error) {
return files.FetchFile(f.reader, f.Name, alignedOffset, count)
})
if err != nil {
f.reader.Log().Error().Err(err).Msg("readat error")
return 0, fmt.Errorf("failed to ReadAt, path: %v, offset: %v, error: %v", f.Name, offset, err.Error())
}
pos := int(offset - alignedOffset)
ret := math.Min(len(buff), len(data)-pos)
ret = copy(buff[:ret], data[pos:pos+ret])
if offset+int64(len(buff)) > fileSize {
err = io.EOF
}
return ret, err
}