/// <summary> /// Creates a memory-backed encoded image from the stream. /// The stream is closed. /// </summary> protected EncodedImage GetByteBufferBackedEncodedImage(Stream inputStream, int length) { var reference = default(CloseableReference <IPooledByteBuffer>); try { if (length <= 0) { reference = CloseableReference <IPooledByteBuffer> .of( _pooledByteBufferFactory.NewByteBuffer(inputStream)); } else { reference = CloseableReference <IPooledByteBuffer> .of( _pooledByteBufferFactory.NewByteBuffer(inputStream, length)); } return(new EncodedImage(reference)); } finally { Closeables.CloseQuietly(inputStream); CloseableReference <IPooledByteBuffer> .CloseSafely(reference); } }
public void Initialize() { // Initializes the IFileCache _fileCacheFactory = new DiskStorageCacheFactory(new DynamicDefaultDiskStorageFactory()); _fileCache = _fileCacheFactory.Get(DiskCacheConfig.NewBuilder().Build()); // Initializes the IPooledByteBufferFactory and PooledByteStreams _poolFactory = new PoolFactory(PoolConfig.NewBuilder().Build()); _byteBufferFactory = _poolFactory.PooledByteBufferFactory; _pooledByteStreams = _poolFactory.PooledByteStreams; // Initializes the IPooledByteBuffer from an image var file = StorageFile.GetFileFromApplicationUriAsync( new Uri("ms-appx:///Assets/SplashScreen.scale-200.png")).GetAwaiter().GetResult(); using (var stream = file.OpenReadAsync().GetAwaiter().GetResult()) { _pooledByteBuffer = _byteBufferFactory.NewByteBuffer( ByteStreams.ToByteArray(stream.AsStream())); } _closeableReference = CloseableReference <IPooledByteBuffer> .of(_pooledByteBuffer); _encodedImage = new EncodedImage(_closeableReference); _stagingArea = StagingArea.Instance; _imageCacheStatsTracker = NoOpImageCacheStatsTracker.Instance; // Initializes the cache keys IList <ICacheKey> keys = new List <ICacheKey>(); keys.Add(new SimpleCacheKey("http://test.uri")); keys.Add(new SimpleCacheKey("http://tyrone.uri")); keys.Add(new SimpleCacheKey("http://ian.uri")); _cacheKey = new MultiCacheKey(keys); // Initializes the executors _isCancelled = new AtomicBoolean(false); _readPriorityExecutor = Executors.NewFixedThreadPool(1); _writePriorityExecutor = Executors.NewFixedThreadPool(1); // Initializes the disk cache _bufferedDiskCache = new BufferedDiskCache( _fileCache, _byteBufferFactory, _pooledByteStreams, _readPriorityExecutor, _writePriorityExecutor, _imageCacheStatsTracker); }
/// <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; } }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <EncodedImage> consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; ImageRequest imageRequest = producerContext.ImageRequest; StatefulProducerRunnable <EncodedImage> cancellableProducerRunnable = new StatefulProducerRunnableImpl <EncodedImage>( consumer, listener, PRODUCER_NAME, requestId, null, null, null, (result) => { IDictionary <string, string> extraMap = new Dictionary <string, string>() { { CREATED_THUMBNAIL, (result != null).ToString() } }; return(new ReadOnlyDictionary <string, string>(extraMap)); }, null, null, (result) => { EncodedImage.CloseSafely(result); }, async() => { Uri sourceUri = imageRequest.SourceUri; StorageFile file = await StorageFile .GetFileFromApplicationUriAsync(sourceUri) .AsTask() .ConfigureAwait(false); using (var fileStream = await file.OpenReadAsync().AsTask().ConfigureAwait(false)) { byte[] bytes = await BitmapUtil .GetThumbnailAsync(fileStream) .ConfigureAwait(false); if (bytes != null) { IPooledByteBuffer pooledByteBuffer = _pooledByteBufferFactory.NewByteBuffer(bytes); return(await BuildEncodedImage(pooledByteBuffer, fileStream) .ConfigureAwait(false)); } else { return(null); } } }); producerContext.AddCallbacks( new BaseProducerContextCallbacks( () => { cancellableProducerRunnable.Cancel(); }, () => { }, () => { }, () => { })); _executor.Execute(cancellableProducerRunnable.Runnable); }