/// <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);
            }
        }
Example #2
0
        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);
        }