@@ -4,18 +4,17 @@ import (
44 "context"
55 "errors"
66 "fmt"
7+ "github.com/OpenListTeam/OpenList/v4/internal/conf"
78 "io"
89 "math"
910 "os"
1011 "sync"
1112
12- "github.com/OpenListTeam/OpenList/v4/internal/conf"
1313 "github.com/OpenListTeam/OpenList/v4/internal/errs"
1414 "github.com/OpenListTeam/OpenList/v4/internal/model"
1515 "github.com/OpenListTeam/OpenList/v4/pkg/buffer"
1616 "github.com/OpenListTeam/OpenList/v4/pkg/http_range"
1717 "github.com/OpenListTeam/OpenList/v4/pkg/utils"
18- "github.com/rclone/rclone/lib/mmap"
1918 "go4.org/readerutil"
2019)
2120
@@ -179,47 +178,53 @@ func (f *FileStream) RangeRead(httpRange http_range.Range) (io.Reader, error) {
179178// 即使被写入的数据量与Buffer.Cap一致,Buffer也会扩大
180179
181180func (f * FileStream ) cache (maxCacheSize int64 ) (model.File , error ) {
182- if maxCacheSize > int64 (conf .MaxBufferLimit ) {
183- tmpF , err := utils .CreateTempFile (f .Reader , f .GetSize ())
184- if err != nil {
185- return nil , err
186- }
187- f .Add (tmpF )
188- f .tmpFile = tmpF
189- f .Reader = tmpF
190- return tmpF , nil
191- }
181+ limit := int64 (conf .MaxBufferLimit )
182+ // TODO: 这里不会改,我写成了buf := make([]byte, 64<<10)的形式
183+ //var buf []byte
184+ //if conf.MmapThreshold > 0 && limit >= int64(conf.MmapThreshold) {
185+ // m, err := mmap.Alloc(int(limit))
186+ // if err == nil {
187+ // f.Add(utils.CloseFunc(func() error {
188+ // return mmap.Free(m)
189+ // }))
190+ // buf = m
191+ // }
192+ //}
192193
193194 if f .peekBuff == nil {
194195 f .peekBuff = & buffer.Reader {}
195196 f .oriReader = f .Reader
196197 }
197- bufSize := maxCacheSize - int64 (f .peekBuff .Len ())
198- var buf []byte
199- if conf .MmapThreshold > 0 && bufSize >= int64 (conf .MmapThreshold ) {
200- m , err := mmap .Alloc (int (bufSize ))
201- if err == nil {
202- f .Add (utils .CloseFunc (func () error {
203- return mmap .Free (m )
204- }))
205- buf = m
198+ var readBytes int
199+ // precache first `limit` byte
200+ for int64 (readBytes ) < limit {
201+ buf := make ([]byte , 64 << 10 )
202+ want := limit - int64 (readBytes )
203+ if want > int64 (len (buf )) {
204+ want = int64 (len (buf ))
205+ }
206+ n , err := f .oriReader .Read (buf [:want ])
207+ if n > 0 {
208+ f .peekBuff .Append (buf [:n ])
209+ readBytes += n
210+ }
211+ if err == io .EOF {
212+ f .Reader = f .peekBuff
213+ f .oriReader = nil
214+ // should update real file size here to solve `GetSize == 0` issue
215+ f .size = int64 (readBytes )
216+ return f .peekBuff , nil
206217 }
207218 }
208- if buf == nil {
209- buf = make ([]byte , bufSize )
210- }
211- n , err := io .ReadFull (f .oriReader , buf )
212- if bufSize != int64 (n ) {
213- return nil , fmt .Errorf ("failed to read all data: (expect =%d, actual =%d) %w" , bufSize , n , err )
214- }
215- f .peekBuff .Append (buf )
216- if int64 (f .peekBuff .Len ()) >= f .GetSize () {
217- f .Reader = f .peekBuff
218- f .oriReader = nil
219- } else {
220- f .Reader = io .MultiReader (f .peekBuff , f .oriReader )
219+ // if file is larger than MaxBufferLimit, fallback to disk
220+ tmpF , err := utils .CreateTempFile (io .MultiReader (f .peekBuff , f .oriReader ), f .GetSize ())
221+ if err != nil {
222+ return nil , err
221223 }
222- return f .peekBuff , nil
224+ f .Add (tmpF )
225+ f .tmpFile = tmpF
226+ f .Reader = tmpF
227+ return tmpF , nil
223228}
224229
225230func (f * FileStream ) SetTmpFile (file model.File ) {
0 commit comments