/// <summary> /// Returns a new CloseableReference to the same underlying /// SharedReference or null if invalid. The SharedReference /// ref-count is incremented. /// </summary> public EncodedImage CloneOrNull() { EncodedImage encodedImage; if (_inputStreamSupplier != null) { encodedImage = new EncodedImage(_inputStreamSupplier, StreamSize); } else { CloseableReference <IPooledByteBuffer> pooledByteBufferRef = CloseableReference <IPooledByteBuffer> .CloneOrNull(_pooledByteBufferRef); try { encodedImage = (pooledByteBufferRef == null) ? null : new EncodedImage(pooledByteBufferRef); } finally { // Close the recently created reference since it will be // cloned again in the constructor. CloseableReference <IPooledByteBuffer> .CloseSafely(pooledByteBufferRef); } } if (encodedImage != null) { encodedImage.CopyMetaDataFrom(this); } return(encodedImage); }
private void MaybeNotifyOnNewResult(CloseableReference <CloseableImage> newRef, bool isLast) { if ((!isLast && !IsClosed()) || (isLast && Close())) { Consumer.OnNewResult(newRef, isLast); } }
public void Initialize() { _byteBufferRef = CloseableReference <IPooledByteBuffer> .of( new TrivialPooledByteBuffer(new byte[] { }), _releaser); _inputStreamSupplier = new MockSupplier <FileStream>(_inputStream); }
public void TestGet() { CloseableReference <byte[]> arrayRef = _pool.Get(1); Assert.AreEqual(0, _delegatePool._freeCounter.NumBytes); Assert.AreEqual(MIN_BUFFER_SIZE, arrayRef.Get().Length); }
/// <summary> /// Verification helpers /// </summary> private void VerifyState( bool isFinished, bool hasResult, CloseableReference <object> resultRef, bool hasFailed, Exception failureCause) { IDataSource <CloseableReference <object> > dataSource = _dataSource; Assert.IsTrue(isFinished == dataSource.IsFinished(), "isFinished"); Assert.IsTrue(hasResult == dataSource.HasResult(), "hasResult"); CloseableReference <object> dataSourceRef = dataSource.GetResult(); AssertReferencesSame("getResult", resultRef, dataSourceRef); CloseableReference <object> .CloseSafely(dataSourceRef); Assert.IsTrue(hasFailed == dataSource.HasFailed(), "hasFailed"); if (failureCause == NPE) { Assert.IsNotNull(dataSource.GetFailureCause(), "failure"); Assert.IsTrue(dataSource.GetFailureCause().GetType() == typeof(NullReferenceException), "failure"); } else { Assert.AreSame(failureCause, dataSource.GetFailureCause(), "failure"); } }
private void UpdateSourceImageRef( CloseableReference <CloseableImage> sourceImageRef, bool isLast) { CloseableReference <CloseableImage> oldSourceImageRef; bool shouldSubmit; lock (_gate) { if (_isClosed) { return; } oldSourceImageRef = _sourceImageRef; _sourceImageRef = CloseableReference <CloseableImage> .CloneOrNull(sourceImageRef); _isLast = isLast; _isDirty = true; shouldSubmit = SetRunningIfDirtyAndNotRunning(); } CloseableReference <CloseableImage> .CloseSafely(oldSourceImageRef); if (shouldSubmit) { SubmitPostprocessing(); } }
/// <summary> /// Gets the value with the given key to be reused, or null if there /// is no such value. /// /// <para />The item can be reused only if it is exclusively owned /// by the cache. /// </summary> public CloseableReference <V> Reuse(K key) { Preconditions.CheckNotNull(key); CloseableReference <V> clientRef = null; bool removed = false; Entry oldExclusive = null; lock (_cacheGate) { oldExclusive = _exclusiveEntries.Remove(key); if (oldExclusive != null) { Entry entry = _cachedEntries.Remove(key); Preconditions.CheckNotNull(entry); Preconditions.CheckState(entry.ClientCount == 0); // Optimization: instead of cloning and then closing the // original reference, we just do a move clientRef = entry.ValueRef; removed = true; } } if (removed) { MaybeNotifyExclusiveEntryRemoval(oldExclusive); } return(clientRef); }
/// <summary> /// Instantiates the <see cref="NativePooledByteBuffer"/>. /// </summary> public NativePooledByteBuffer(CloseableReference <NativeMemoryChunk> bufRef, int size) { Preconditions.CheckNotNull(bufRef); Preconditions.CheckArgument(size >= 0 && size <= bufRef.Get().Size); _bufRef = bufRef.Clone(); _size = size; }
/// <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); } }
/// <summary> /// Ensure that the current stream is valid, that is underlying /// closeable reference is not null and is valid. /// </summary> /// <exception cref="InvalidStreamException"> /// If the stream is invalid. /// </exception> private void EnsureValid() { if (!CloseableReference <NativeMemoryChunk> .IsValid(_bufRef)) { throw new InvalidStreamException(); } }
private void SubmitPostprocessing() { _parent._executor.Execute(() => { CloseableReference <CloseableImage> closeableImageRef; bool isLast; lock (_gate) { // instead of cloning and closing the reference, we do a more // efficient move. closeableImageRef = _sourceImageRef; isLast = _isLast; _sourceImageRef = null; _isDirty = false; } if (CloseableReference <CloseableImage> .IsValid(closeableImageRef)) { try { DoPostprocessing(closeableImageRef, isLast); } finally { CloseableReference <CloseableImage> .CloseSafely(closeableImageRef); } } ClearRunningAndStartIfDirty(); }); }
/// <summary> /// Called whenever a new value is ready to be retrieved from /// the IDataSource. /// </summary> public override async Task OnNewResultImpl( IDataSource <CloseableReference <CloseableImage> > dataSource) { if (!dataSource.IsFinished()) { return; } CloseableReference <CloseableImage> closeableImageRef = dataSource.GetResult(); SoftwareBitmap bitmap = null; if (closeableImageRef != null && (closeableImageRef.Get().GetType() == typeof(CloseableBitmap) || closeableImageRef.Get().GetType() == typeof(CloseableStaticBitmap))) { bitmap = ((CloseableBitmap)closeableImageRef.Get()).UnderlyingBitmap; } try { await OnNewResultImpl(bitmap).ConfigureAwait(false); } finally { CloseableReference <CloseableImage> .CloseSafely(closeableImageRef); } }
public void TestEviction_ByEvictionQueueSize() { CloseableReference <int> originalRef1 = NewReference(200); CloseableReference <int> valueRef1 = _cache.Cache(KEYS[1], originalRef1); originalRef1.Dispose(); valueRef1.Dispose(); CloseableReference <int> originalRef2 = NewReference(300); CloseableReference <int> valueRef2 = _cache.Cache(KEYS[2], originalRef2); originalRef2.Dispose(); valueRef2.Dispose(); CloseableReference <int> originalRef3 = NewReference(700); CloseableReference <int> valueRef3 = _cache.Cache(KEYS[3], originalRef3); originalRef3.Dispose(); AssertTotalSize(3, 1200); AssertExclusivelyOwnedSize(2, 500); AssertExclusivelyOwned(KEYS[1], 200); AssertExclusivelyOwned(KEYS[2], 300); AssertSharedWithCount(KEYS[3], 700, 1); Assert.AreEqual(0, _releaseCallCount); // Closing the client reference for item3 will cause item1 to be evicted valueRef3.Dispose(); AssertTotalSize(2, 1000); AssertExclusivelyOwnedSize(2, 1000); AssertNotCached(KEYS[1], 200); AssertExclusivelyOwned(KEYS[2], 300); AssertExclusivelyOwned(KEYS[3], 700); Assert.IsTrue(_releaseValues.Contains(200)); }
public void TestClone() { CloseableReference <IDisposable> copy = _closeableReference.Clone(); Assert.AreEqual(2, _closeableReference.GetUnderlyingReferenceTestOnly().GetRefCountTestOnly()); Assert.AreSame(_closeableReference.GetUnderlyingReferenceTestOnly(), copy.GetUnderlyingReferenceTestOnly()); }
public void TestUpdatesCacheParams() { CloseableReference <int> originalRef = NewReference(700); CloseableReference <int> cachedRef = _cache.Cache(KEYS[2], originalRef); originalRef.Dispose(); cachedRef.Dispose(); _cache.Get(KEY); Assert.AreEqual(1, _paramsSupplier.GetCallCount); _cache.Get(KEY); Assert.AreEqual(1, _paramsSupplier.GetCallCount); _cache.Get(KEY); Assert.AreEqual(1, _paramsSupplier.GetCallCount); AssertTotalSize(1, 700); AssertExclusivelyOwnedSize(1, 700); _params = new MemoryCacheParams( 500 /* cache max size */, CACHE_MAX_COUNT, CACHE_EVICTION_QUEUE_MAX_SIZE, CACHE_EVICTION_QUEUE_MAX_COUNT, CACHE_ENTRY_MAX_SIZE); _paramsSupplier = new MockSupplier <MemoryCacheParams>(_params); _cache.ForceUpdateCacheParams(_paramsSupplier); _cache.Get(KEY); Assert.AreEqual(1, _paramsSupplier.GetCallCount); AssertTotalSize(0, 0); AssertExclusivelyOwnedSize(0, 0); Assert.IsTrue(_releaseValues.Contains(700)); }
public void TestCachingSameKeyTwice() { CloseableReference <int> originalRef1 = NewReference(110); CloseableReference <int> cachedRef1 = _cache.Cache(KEY, originalRef1); CloseableReference <int> cachedRef2a = _cache.Get(KEY); CloseableReference <int> cachedRef2b = cachedRef2a.Clone(); CloseableReference <int> cachedRef3 = _cache.Get(KEY); CountingMemoryCache <string, int> .Entry entry1 = _cache._cachedEntries.Get(KEY); CloseableReference <int> cachedRef2 = _cache.Cache(KEY, NewReference(120)); CountingMemoryCache <string, int> .Entry entry2 = _cache._cachedEntries.Get(KEY); Assert.AreNotSame(entry1, entry2); AssertOrphanWithCount(entry1, 3); AssertSharedWithCount(KEY, 120, 1); // Release the orphaned reference only when all clients are gone originalRef1.Dispose(); cachedRef2b.Dispose(); AssertOrphanWithCount(entry1, 3); cachedRef2a.Dispose(); AssertOrphanWithCount(entry1, 2); cachedRef1.Dispose(); AssertOrphanWithCount(entry1, 1); Assert.AreEqual(0, _releaseCallCount); cachedRef3.Dispose(); AssertOrphanWithCount(entry1, 0); Assert.AreEqual(1, _releaseCallCount); }
/// <summary> /// Creates a new entry with the usage count of 0. /// </summary> internal static Entry of( K key, CloseableReference <V> valueRef, IEntryStateObserver <K> observer) { return(new Entry(key, valueRef, observer)); }
public void TestTrimUnsuccessful() { CloseableReference <byte[]> arrayRef = _pool.Get(7); _delegatePool.Trim(MemoryTrimType.OnCloseToDalvikHeapLimit); Assert.IsNotNull(arrayRef.Get()); }
/// <summary> /// Creates a new reference for the client. /// </summary> private CloseableReference <V> NewClientReference(Entry entry) { IncreaseClientCount(entry); return(CloseableReference <V> .of( entry.ValueRef.Get(), new ResourceReleaserImpl <V>(v => ReleaseClientReference(entry)))); }
public void TestConvert() { CloseableReference <SoftwareBitmap> reference = _closeableStaticBitmap.ConvertToBitmapReference(); Assert.AreSame(reference.Get(), _bitmap); Assert.IsTrue(_closeableStaticBitmap.IsClosed); }
/// <summary> /// Creates a bitmap of the specified width and height. This is intended for ImagePipeline's /// internal use only. /// /// <param name="width">the width of the bitmap</param> /// <param name="height">the height of the bitmap</param> /// <param name="bitmapConfig">the Bitmap.Config used to create the Bitmap</param> /// <returns>a reference to the bitmap</returns> /// <exception cref="OutOfMemoryException">if the Bitmap cannot be allocated</exception> /// </summary> public override CloseableReference <SoftwareBitmap> CreateBitmapInternal( int width, int height, BitmapPixelFormat bitmapConfig) { _bitmap = new SoftwareBitmap(bitmapConfig, width, height); return(CloseableReference <SoftwareBitmap> .of(_bitmap, BITMAP_RESOURCE_RELEASER)); }
private void VerifyReferenceCount(CloseableReference <object> resultRef) { // this unit test class keeps references alive, so their ref count must be 1; // except for the result which have ref count of 2 because it's also kept by data source AssertReferenceCount((resultRef == _resultRef1) ? 2 : 1, _resultRef1); AssertReferenceCount((resultRef == _resultRef2) ? 2 : 1, _resultRef2); AssertReferenceCount((resultRef == _resultRef3) ? 2 : 1, _resultRef3); }
/// <summary> /// Instantiates the <see cref="EncodedImage"/> with provided params /// </summary> public EncodedImage(CloseableReference <IPooledByteBuffer> pooledByteBufferRef) { Preconditions.CheckArgument( CloseableReference <IPooledByteBuffer> .IsValid(pooledByteBufferRef)); _pooledByteBufferRef = pooledByteBufferRef.Clone(); _inputStreamSupplier = null; }
public void TestGet() { CloseableReference <byte[]> arrayRef = _array.Get(1); Assert.AreSame(_array._byteArraySoftRef.Get(), arrayRef.Get()); Assert.AreEqual(4, arrayRef.Get().Length); Assert.AreEqual(0, _array._semaphore.CurrentCount); }
/// <summary> /// Closes the stream. Owned resources are released back to the pool. /// It is not allowed to call ToByteBuffer after call to this method. /// </summary> protected override void Dispose(bool disposing) { base.Dispose(disposing); CloseableReference <NativeMemoryChunk> .CloseSafely(_bufRef); _bufRef = null; _count = -1; }
public void TestTrimUnsuccessful() { CloseableReference <byte[]> arrayRef = _array.Get(7); _array.Trim(MemoryTrimType.OnCloseToDalvikHeapLimit); Assert.AreSame(arrayRef.Get(), _array._byteArraySoftRef.Get()); Assert.AreEqual(0, _array._semaphore.CurrentCount); }
private Entry(K key, CloseableReference <V> valueRef, IEntryStateObserver <K> observer) { Key = Preconditions.CheckNotNull(key); ValueRef = Preconditions.CheckNotNull(CloseableReference <V> .CloneOrNull(valueRef)); ClientCount = 0; Orphan = false; Observer = observer; }
public void TestAddBitmapReference() { using (CloseableReference <SoftwareBitmap> bitmapReference = _platformBitmapFactory.CreateBitmap(50, 50)) { Assert.IsNotNull(bitmapReference); Assert.AreEqual(1, _platformBitmapFactory.AddBitmapReferenceCallCount); Assert.AreEqual(bitmapReference.Get(), _platformBitmapFactory.Bitmap); } }
public void TestToggleExclusive() { CloseableReference <int> cachedRef = _cache.Cache(KEY, NewReference(100), _entryStateObserver); cachedRef.Dispose(); Assert.IsTrue(_isExclusive ?? false); _cache.Get(KEY); Assert.IsFalse(_isExclusive ?? true); }
/// <summary> /// Cleanup resources. /// </summary> private void Dispose(bool disposing) { lock (_poolGate) { CloseableReference <NativeMemoryChunk> .CloseSafely(_bufRef); _bufRef = null; } }