public void TestCloneOrNull()
        {
            EncodedImage encodedImage = new EncodedImage(_byteBufferRef);

            encodedImage.Format        = ImageFormat.JPEG;
            encodedImage.RotationAngle = 0;
            encodedImage.Width         = 1;
            encodedImage.Height        = 2;
            encodedImage.SampleSize    = 4;
            EncodedImage encodedImage2 = EncodedImage.CloneOrNull(encodedImage);

            Assert.AreEqual(3, _byteBufferRef.GetUnderlyingReferenceTestOnly().GetRefCountTestOnly());
            Assert.AreSame(
                encodedImage.GetByteBufferRef().GetUnderlyingReferenceTestOnly(),
                encodedImage2.GetByteBufferRef().GetUnderlyingReferenceTestOnly());
            Assert.AreEqual(encodedImage.Format, encodedImage2.Format);
            Assert.AreEqual(encodedImage.RotationAngle, encodedImage2.RotationAngle);
            Assert.AreEqual(encodedImage.Height, encodedImage2.Height);
            Assert.AreEqual(encodedImage.Width, encodedImage2.Width);
            Assert.AreEqual(encodedImage.SampleSize, encodedImage2.SampleSize);

            encodedImage               = new EncodedImage(_inputStreamSupplier, 100);
            encodedImage.Format        = ImageFormat.JPEG;
            encodedImage.RotationAngle = 0;
            encodedImage.Width         = 1;
            encodedImage.Height        = 2;
            encodedImage2              = EncodedImage.CloneOrNull(encodedImage);
            Assert.AreSame(encodedImage.GetInputStream(), encodedImage2.GetInputStream());
            Assert.AreEqual(encodedImage2.Size, encodedImage.Size);
        }
        public void TestCloneOrNull_WithInvalidOrNullReferences()
        {
            Assert.AreEqual(null, EncodedImage.CloneOrNull(null));
            EncodedImage encodedImage = new EncodedImage(_byteBufferRef);

            encodedImage.Dispose();
            Assert.AreEqual(null, EncodedImage.CloneOrNull(encodedImage));
        }
        /// <summary>
        /// Associates encodedImage with given key in disk cache.
        /// Disk write is performed on background thread, so the
        /// caller of this method is not blocked.
        /// </summary>
        public Task Put(ICacheKey key, EncodedImage encodedImage)
        {
            Preconditions.CheckNotNull(key);
            Preconditions.CheckArgument(EncodedImage.IsValid(encodedImage));

            // Store encodedImage in staging area
            _stagingArea.Put(key, encodedImage);

            // Write to disk cache. This will be executed on background thread,
            // so increment the ref count. When this write completes
            // (with success/failure), then we will bump down the ref count again.
            EncodedImage finalEncodedImage = EncodedImage.CloneOrNull(encodedImage);

            try
            {
                Task writeTask = _writeExecutor.Execute(() =>
                {
                    try
                    {
                        WriteToDiskCache(key, finalEncodedImage);
                    }
                    finally
                    {
                        _stagingArea.Remove(key, finalEncodedImage);
                        EncodedImage.CloseSafely(finalEncodedImage);

                        // Removes write task after it's completed.
                        Task writeTaskCompleted = default(Task);
                        _writeToDiskCacheTasks.TryRemove(key, out writeTaskCompleted);
                    }
                });

                _writeToDiskCacheTasks.TryAdd(key, writeTask);
                return(writeTask);
            }
            catch (Exception)
            {
                // We failed to enqueue cache write. Log failure and decrement ref count
                // TODO: 3697790
                Debug.WriteLine($"Failed to schedule disk-cache write for { key.ToString() }");
                _stagingArea.Remove(key, encodedImage);
                EncodedImage.CloseSafely(finalEncodedImage);

                // Removes write task due to error.
                Task writeTaskCompleted = default(Task);
                _writeToDiskCacheTasks.TryRemove(key, out writeTaskCompleted);
                throw;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Updates the job.
        ///
        /// <para />This just updates the job, but it doesn't schedule it.
        /// In order to be executed, the job has to be scheduled after
        /// being set. In case there was a previous job scheduled that has
        /// not yet started, this new job will be executed instead.
        /// </summary>
        /// <returns>
        /// Whether the job was successfully updated.
        /// </returns>
        public bool UpdateJob(EncodedImage encodedImage, bool isLast)
        {
            if (!ShouldProcess(encodedImage, isLast))
            {
                return(false);
            }

            EncodedImage oldEncodedImage;

            lock (_gate)
            {
                oldEncodedImage = _encodedImage;
                _encodedImage   = EncodedImage.CloneOrNull(encodedImage);
                _isLast         = isLast;
            }

            EncodedImage.CloseSafely(oldEncodedImage);
            return(true);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Stores key-value in this StagingArea.
        /// </summary>
        /// <param name="key">The cache key.</param>
        /// <param name="encodedImage">
        /// EncodedImage to be associated with key.
        /// </param>
        public void Put(ICacheKey key, EncodedImage encodedImage)
        {
            lock (_mapGate)
            {
                Preconditions.CheckNotNull(key);
                Preconditions.CheckArgument(EncodedImage.IsValid(encodedImage));

                // We're making a 'copy' of this reference - so duplicate it
                EncodedImage oldEntry = default(EncodedImage);
                if (_map.TryGetValue(key, out oldEntry))
                {
                    _map.Remove(key);
                }

                _map.Add(key, EncodedImage.CloneOrNull(encodedImage));
                EncodedImage.CloseSafely(oldEntry);
#if DEBUG_STAGING_AREA
                LogStats();
#endif // DEBUG_STAGING_AREA
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets the encoded image.
        /// </summary>
        /// <returns>
        /// Value associated with given key or null if no value is associated.
        /// </returns>
        public EncodedImage Get(ICacheKey key)
        {
            lock (_mapGate)
            {
                Preconditions.CheckNotNull(key);
                EncodedImage storedEncodedImage = default(EncodedImage);
                if (_map.TryGetValue(key, out storedEncodedImage))
                {
                    if (!EncodedImage.IsValid(storedEncodedImage))
                    {
                        // Reference is not valid, this means that someone
                        // cleared reference while it was still in use.
                        // Log error TODO: 3697790
                        _map.Remove(key);
                        Debug.WriteLine($"Found closed reference { storedEncodedImage.GetHashCode() } for key { key.ToString() } ({ key.GetHashCode() })");
                        return(null);
                    }

                    storedEncodedImage = EncodedImage.CloneOrNull(storedEncodedImage);
                }

                return(storedEncodedImage);
            }
        }
 /// <summary>
 /// Clones the result.
 /// </summary>
 public override EncodedImage CloneOrNull(EncodedImage encodedImage)
 {
     return(EncodedImage.CloneOrNull(encodedImage));
 }