MCPcopy
hub / github.com/rclone/rclone / getChunk

Method getChunk

backend/cache/handle.go:203–259  ·  view source on GitHub ↗

getChunk is called by the FS to retrieve a specific chunk of known start and size from where it can find it it can be from transient or persistent cache it will also build the chunk from the cache's specific chunk boundaries and build the final desired chunk in a buffer

(chunkStart int64)

Source from the content-addressed store, hash-verified

201// it can be from transient or persistent cache
202// it will also build the chunk from the cache's specific chunk boundaries and build the final desired chunk in a buffer
203func (r *Handle) getChunk(chunkStart int64) ([]byte, error) {
204 var data []byte
205 var err error
206
207 // we calculate the modulus of the requested offset with the size of a chunk
208 offset := chunkStart % int64(r.cacheFs().opt.ChunkSize)
209
210 // we align the start offset of the first chunk to a likely chunk in the storage
211 chunkStart -= offset
212 r.queueOffset(chunkStart)
213 found := false
214
215 if r.UseMemory {
216 data, err = r.memory.GetChunk(r.cachedObject, chunkStart)
217 if err == nil {
218 found = true
219 }
220 }
221
222 if !found {
223 // we're gonna give the workers a chance to pickup the chunk
224 // and retry a couple of times
225 for i := range r.cacheFs().opt.ReadRetries * 8 {
226 data, err = r.storage().GetChunk(r.cachedObject, chunkStart)
227 if err == nil {
228 found = true
229 break
230 }
231
232 fs.Debugf(r, "%v: chunk retry storage: %v", chunkStart, i)
233 time.Sleep(time.Millisecond * 500)
234 }
235 }
236
237 // not found in ram or
238 // the worker didn't managed to download the chunk in time so we abort and close the stream
239 if err != nil || len(data) == 0 || !found {
240 if r.workers == 0 {
241 fs.Errorf(r, "out of workers")
242 return nil, io.ErrUnexpectedEOF
243 }
244
245 return nil, fmt.Errorf("chunk not found %v", chunkStart)
246 }
247
248 // first chunk will be aligned with the start
249 if offset > 0 {
250 if offset > int64(len(data)) {
251 fs.Errorf(r, "unexpected conditions during reading. current position: %v, current chunk position: %v, current chunk size: %v, offset: %v, chunk size: %v, file size: %v",
252 r.offset, chunkStart, len(data), offset, r.cacheFs().opt.ChunkSize, r.cachedObject.Size())
253 return nil, io.ErrUnexpectedEOF
254 }
255 data = data[int(offset):]
256 }
257
258 return data, nil
259}
260

Callers 2

ReadMethod · 0.95
rcFetchMethod · 0.45

Calls 8

cacheFsMethod · 0.95
queueOffsetMethod · 0.95
storageMethod · 0.95
DebugfFunction · 0.92
ErrorfFunction · 0.92
SizeMethod · 0.65
GetChunkMethod · 0.45
ErrorfMethod · 0.45

Tested by

no test coverage detected