github.com/Synthesix/Sia@v1.3.3-0.20180413141344-f863baeed3ca/modules/renter/downloadcache.go (about) 1 package renter 2 3 // TODO expose the downloadCacheSize as a variable and allow users to set it 4 // via the API. 5 6 import ( 7 "time" 8 9 "github.com/NebulousLabs/errors" 10 ) 11 12 // addChunkToCache adds the chunk to the cache if the download is a streaming 13 // endpoint download. 14 // TODO this won't be necessary anymore once we have partial downloads. 15 func (udc *unfinishedDownloadChunk) addChunkToCache(data []byte) { 16 if udc.download.staticDestinationType == destinationTypeSeekStream { 17 // We only cache streaming chunks since browsers and media players tend to only request a few kib at once when streaming data. That way we can prevent scheduling the same chunk for download over and over. 18 return 19 } 20 udc.cacheMu.Lock() 21 // Prune cache if necessary. 22 // TODO insteado of deleting a 'random' key, delete the 23 // least-recently-accessed element of the cache. 24 for key := range udc.chunkCache { 25 if len(udc.chunkCache) < downloadCacheSize { 26 break 27 } 28 delete(udc.chunkCache, key) 29 } 30 udc.chunkCache[udc.staticCacheID] = data 31 udc.cacheMu.Unlock() 32 } 33 34 // managedTryCache tries to retrieve the chunk from the renter's cache. If 35 // successful it will write the data to the destination and stop the download 36 // if it was the last missing chunk. The function returns true if the chunk was 37 // in the cache. 38 // TODO in the future we might need cache invalidation. At the 39 // moment this doesn't worry us since our files are static. 40 func (r *Renter) managedTryCache(udc *unfinishedDownloadChunk) bool { 41 udc.mu.Lock() 42 defer udc.mu.Unlock() 43 r.cmu.Lock() 44 data, cached := r.chunkCache[udc.staticCacheID] 45 r.cmu.Unlock() 46 if !cached { 47 return false 48 } 49 start := udc.staticFetchOffset 50 end := start + udc.staticFetchLength 51 _, err := udc.destination.WriteAt(data[start:end], udc.staticWriteOffset) 52 if err != nil { 53 r.log.Println("WARN: failed to write cached chunk to destination:", err) 54 udc.fail(errors.AddContext(err, "failed to write cached chunk to destination")) 55 return true 56 } 57 58 // Check if the download is complete now. 59 udc.download.mu.Lock() 60 udc.download.chunksRemaining-- 61 if udc.download.chunksRemaining == 0 { 62 udc.download.endTime = time.Now() 63 close(udc.download.completeChan) 64 } 65 udc.download.mu.Unlock() 66 return true 67 }