/// <summary> /// Inserts resource into file with key. /// </summary> /// <param name="key">Cache key.</param> /// <param name="callback"> /// Callback that writes to an output stream. /// </param> /// <returns>A sequence of bytes.</returns> public IBinaryResource Insert(ICacheKey key, IWriterCallback callback) { // Write to a temp file, then move it into place. // This allows more parallelism when writing files. SettableCacheEvent cacheEvent = SettableCacheEvent.Obtain().SetCacheKey(key); _cacheEventListener.OnWriteAttempt(cacheEvent); string resourceId; lock (_lock) { // For multiple resource ids associated with the same image, // we only write one file resourceId = CacheKeyUtil.GetFirstResourceId(key); } cacheEvent.SetResourceId(resourceId); try { // Getting the file is synchronized IInserter inserter = StartInsert(resourceId, key); try { inserter.WriteData(callback, key); // Committing the file is synchronized IBinaryResource resource = EndInsert(inserter, key, resourceId); cacheEvent.SetItemSize(resource.GetSize()) .SetCacheSize(_cacheStats.Size); _cacheEventListener.OnWriteSuccess(cacheEvent); return(resource); } finally { if (!inserter.CleanUp()) { Debug.WriteLine("Failed to delete temp file"); } } } catch (IOException ioe) { cacheEvent.SetException(ioe); _cacheEventListener.OnWriteException(cacheEvent); Debug.WriteLine("Failed inserting a file into the cache"); throw; } finally { cacheEvent.Recycle(); } }
/// <summary> /// Commits the provided temp file to the cache, renaming it to match /// the cache's hashing convention. /// </summary> private IBinaryResource EndInsert( IInserter inserter, ICacheKey key, string resourceId) { lock (_lock) { IBinaryResource resource = inserter.Commit(key); _resourceIndex.Add(resourceId); _cacheStats.Increment(resource.GetSize(), 1); return(resource); } }
/// <summary> /// Performs disk cache read. In case of any exception null is returned. /// </summary> private IPooledByteBuffer ReadFromDiskCache(ICacheKey key) { try { Debug.WriteLine($"Disk cache read for { key.ToString() }"); IBinaryResource diskCacheResource = _fileCache.GetResource(key); if (diskCacheResource == null) { Debug.WriteLine($"Disk cache miss for { key.ToString() }"); _imageCacheStatsTracker.OnDiskCacheMiss(); return(null); } else { Debug.WriteLine($"Found entry in disk cache for { key.ToString() }"); _imageCacheStatsTracker.OnDiskCacheHit(); } IPooledByteBuffer byteBuffer; using (Stream inputStream = diskCacheResource.OpenStream()) { byteBuffer = _pooledByteBufferFactory.NewByteBuffer( inputStream, (int)diskCacheResource.GetSize()); } Debug.WriteLine($"Successful read from disk cache for { key.ToString() }"); return(byteBuffer); } catch (Exception) { // TODO: 3697790 log failures // TODO: 5258772 - uncomment line below // _fileCache.Remove(key); Debug.WriteLine($"Exception reading from cache for { key.ToString() }"); _imageCacheStatsTracker.OnDiskCacheGetFail(); throw; } }