public void TestCanReuseExclusive() { CloseableReference <int> cachedRef = _cache.Cache(KEY, NewReference(100), _entryStateObserver); cachedRef.Dispose(); Assert.IsTrue(_isExclusive ?? false); cachedRef = _cache.Reuse(KEY); Assert.IsNotNull(cachedRef); Assert.IsFalse(_isExclusive ?? true); cachedRef.Dispose(); Assert.IsFalse(_isExclusive ?? true); }
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); }
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 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 TestCloseReference() { CloseableReference <IDisposable> copy = _closeableReference.Clone(); Assert.AreEqual(2, _closeableReference.GetUnderlyingReferenceTestOnly().GetRefCountTestOnly()); copy.Dispose(); Assert.AreEqual(1, _closeableReference.GetUnderlyingReferenceTestOnly().GetRefCountTestOnly()); }
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> /// This has to be called before we get rid of this object in order to /// release underlying memory. /// </summary> protected override void Dispose(bool disposing) { base.Dispose(disposing); CloseableReference <SoftwareBitmap> reference = DetachBitmapReference(); if (reference != null) { reference.Dispose(); } }
public void TestClosingClientReference() { CloseableReference <int> cachedRef = _cache.Cache(KEY, NewReference(100)); // cached item should get exclusively owned cachedRef.Dispose(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(1, 100); AssertExclusivelyOwned(KEY, 100); Assert.AreEqual(0, _releaseCallCount); }
public void TestGet_Realloc() { CloseableReference <byte[]> arrayRef = _pool.Get(1); byte[] smallArray = arrayRef.Get(); arrayRef.Dispose(); arrayRef = _pool.Get(7); Assert.AreEqual(8, arrayRef.Get().Length); Assert.AreNotSame(smallArray, arrayRef.Get()); }
public void TestClosingOriginalReference() { CloseableReference <int> originalRef = NewReference(100); _cache.Cache(KEY, originalRef); // cache should make its own copy and closing the original reference after caching // should not affect the cached value originalRef.Dispose(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEY, 100, 1); Assert.AreEqual(0, _releaseCallCount); }
public void TestEviction_ByTotalCount() { // value 5 cannot fit the cache CloseableReference <int> originalRef1 = NewReference(110); CloseableReference <int> valueRef1 = _cache.Cache(KEYS[1], originalRef1); originalRef1.Dispose(); CloseableReference <int> originalRef2 = NewReference(120); CloseableReference <int> valueRef2 = _cache.Cache(KEYS[2], originalRef2); originalRef2.Dispose(); CloseableReference <int> originalRef3 = NewReference(130); CloseableReference <int> valueRef3 = _cache.Cache(KEYS[3], originalRef3); originalRef3.Dispose(); CloseableReference <int> originalRef4 = NewReference(140); CloseableReference <int> valueRef4 = _cache.Cache(KEYS[4], originalRef4); originalRef4.Dispose(); CloseableReference <int> originalRef5 = NewReference(150); CloseableReference <int> valueRef5 = _cache.Cache(KEYS[5], originalRef5); originalRef5.Dispose(); AssertTotalSize(4, 500); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEYS[1], 110, 1); AssertSharedWithCount(KEYS[2], 120, 1); AssertSharedWithCount(KEYS[3], 130, 1); AssertSharedWithCount(KEYS[4], 140, 1); AssertNotCached(KEYS[5], 150); Assert.IsNull(valueRef5); // Closing the clients of cached items will make them viable for eviction valueRef1.Dispose(); valueRef2.Dispose(); valueRef3.Dispose(); AssertTotalSize(4, 500); AssertExclusivelyOwnedSize(3, 360); // Value 4 can now fit after evicting value1 valueRef4 = _cache.Cache(KEYS[5], NewReference(150)); AssertTotalSize(4, 540); AssertExclusivelyOwnedSize(2, 250); AssertNotCached(KEYS[1], 110); AssertExclusivelyOwned(KEYS[2], 120); AssertExclusivelyOwned(KEYS[3], 130); AssertSharedWithCount(KEYS[4], 140, 1); AssertSharedWithCount(KEYS[5], 150, 1); Assert.IsTrue(_releaseValues.Contains(110)); }
/// <summary> /// Reallocate the local buffer to hold the new length specified. /// Also copy over existing data to this new buffer. /// </summary> /// <param name="newLength">New length of buffer.</param> /// <exception cref="InvalidStreamException"> /// If the stream is invalid. /// </exception> /// <exception cref="SizeTooLargeException"> /// If the allocation from the pool fails. /// </exception> internal void Realloc(int newLength) { EnsureValid(); /* Can the buffer handle @i more bytes, if not expand it */ if (newLength <= _bufRef.Get().Size) { return; } NativeMemoryChunk newbuf = _pool.Get(newLength); _bufRef.Get().Copy(0, newbuf, 0, _count); _bufRef.Dispose(); _bufRef = CloseableReference <NativeMemoryChunk> .of(newbuf, _pool); }
public void TestInUseCount() { CloseableReference <int> cachedRef1 = _cache.Cache(KEY, NewReference(100)); CloseableReference <int> cachedRef2a = _cache.Get(KEY); CloseableReference <int> cachedRef2b = cachedRef2a.Clone(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEY, 100, 2); CloseableReference <int> cachedRef3a = _cache.Get(KEY); CloseableReference <int> cachedRef3b = cachedRef3a.Clone(); CloseableReference <int> cachedRef3c = cachedRef3b.Clone(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEY, 100, 3); cachedRef1.Dispose(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEY, 100, 2); // All copies of cachedRef2a need to be closed for usage count to drop cachedRef2a.Dispose(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEY, 100, 2); cachedRef2b.Dispose(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEY, 100, 1); // All copies of cachedRef3a need to be closed for usage count to drop cachedRef3c.Dispose(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEY, 100, 1); cachedRef3b.Dispose(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEY, 100, 1); cachedRef3a.Dispose(); AssertTotalSize(1, 100); AssertExclusivelyOwnedSize(1, 100); AssertExclusivelyOwned(KEY, 100); }
public void TestEviction_ByTotalSize() { // Value 4 cannot fit the cache CloseableReference <int> originalRef1 = NewReference(400); CloseableReference <int> valueRef1 = _cache.Cache(KEYS[1], originalRef1); originalRef1.Dispose(); CloseableReference <int> originalRef2 = NewReference(500); CloseableReference <int> valueRef2 = _cache.Cache(KEYS[2], originalRef2); originalRef2.Dispose(); CloseableReference <int> originalRef3 = NewReference(100); CloseableReference <int> valueRef3 = _cache.Cache(KEYS[3], originalRef3); originalRef3.Dispose(); CloseableReference <int> originalRef4 = NewReference(700); CloseableReference <int> valueRef4 = _cache.Cache(KEYS[4], originalRef4); originalRef4.Dispose(); AssertTotalSize(3, 1000); AssertExclusivelyOwnedSize(0, 0); AssertSharedWithCount(KEYS[1], 400, 1); AssertSharedWithCount(KEYS[2], 500, 1); AssertSharedWithCount(KEYS[3], 100, 1); AssertNotCached(KEYS[4], 700); Assert.IsNull(valueRef4); // Closing the clients of cached items will make them viable for eviction valueRef1.Dispose(); valueRef2.Dispose(); valueRef3.Dispose(); AssertTotalSize(3, 1000); AssertExclusivelyOwnedSize(3, 1000); // Value 4 can now fit after evicting value1 and value2 valueRef4 = _cache.Cache(KEYS[4], NewReference(700)); AssertTotalSize(2, 800); AssertExclusivelyOwnedSize(1, 100); AssertNotCached(KEYS[1], 400); AssertNotCached(KEYS[2], 500); AssertExclusivelyOwned(KEYS[3], 100); AssertSharedWithCount(KEYS[4], 700, 1); Assert.IsTrue(_releaseValues.Contains(400)); Assert.IsTrue(_releaseValues.Contains(500)); }
public void TestRemoveAllMatchingPredicate() { CloseableReference <int> originalRef1 = NewReference(110); CloseableReference <int> valueRef1 = _cache.Cache(KEYS[1], originalRef1); originalRef1.Dispose(); valueRef1.Dispose(); CloseableReference <int> originalRef2 = NewReference(120); CloseableReference <int> valueRef2 = _cache.Cache(KEYS[2], originalRef2); originalRef2.Dispose(); valueRef2.Dispose(); CloseableReference <int> originalRef3 = NewReference(130); CloseableReference <int> valueRef3 = _cache.Cache(KEYS[3], originalRef3); originalRef3.Dispose(); CountingMemoryCache <string, int> .Entry entry3 = _cache._cachedEntries.Get(KEYS[3]); CloseableReference <int> originalRef4 = NewReference(150); CloseableReference <int> valueRef4 = _cache.Cache(KEYS[4], originalRef4); originalRef4.Dispose(); int numEvictedEntries = _cache.RemoveAll( new Predicate <string>(key => key.Equals(KEYS[2]) || key.Equals(KEYS[3]))); Assert.AreEqual(2, numEvictedEntries); AssertTotalSize(2, 260); AssertExclusivelyOwnedSize(1, 110); AssertExclusivelyOwned(KEYS[1], 110); AssertNotCached(KEYS[2], 120); AssertOrphanWithCount(entry3, 1); AssertSharedWithCount(KEYS[4], 150, 1); Assert.IsTrue(_releaseValues.Contains(120)); Assert.IsFalse(_releaseValues.Contains(130)); valueRef3.Dispose(); Assert.IsTrue(_releaseValues.Contains(130)); }
public void TestClear() { CloseableReference <int> originalRef1 = NewReference(110); CloseableReference <int> cachedRef1 = _cache.Cache(KEYS[1], originalRef1); originalRef1.Dispose(); CountingMemoryCache <string, int> .Entry entry1 = _cache._cachedEntries.Get(KEYS[1]); CloseableReference <int> originalRef2 = NewReference(120); CloseableReference <int> cachedRef2 = _cache.Cache(KEYS[2], originalRef2); originalRef2.Dispose(); cachedRef2.Dispose(); _cache.Clear(); AssertTotalSize(0, 0); AssertExclusivelyOwnedSize(0, 0); AssertOrphanWithCount(entry1, 1); AssertNotCached(KEYS[2], 120); Assert.IsTrue(_releaseValues.Contains(120)); cachedRef1.Dispose(); Assert.IsTrue(_releaseValues.Contains(110)); }
/// <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 <CloseableReference <CloseableImage> > consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; listener.OnProducerStart(requestId, ProducerName); ImageRequest imageRequest = producerContext.ImageRequest; object callerContext = producerContext.CallerContext; ICacheKey cacheKey = _cacheKeyFactory.GetBitmapCacheKey(imageRequest, callerContext); IDictionary <string, string> extraMap = default(IDictionary <string, string>); CloseableReference <CloseableImage> cachedReference = _memoryCache.Get(cacheKey); if (cachedReference != null) { bool isFinal = cachedReference.Get().QualityInfo.IsOfFullQuality; if (isFinal) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "true" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnProgressUpdate(1f); } consumer.OnNewResult(cachedReference, isFinal); cachedReference.Dispose(); if (isFinal) { return; } } if (producerContext.LowestPermittedRequestLevel >= RequestLevel.BITMAP_MEMORY_CACHE) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnNewResult(null, true); return; } extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; IConsumer <CloseableReference <CloseableImage> > wrappedConsumer = WrapConsumer(consumer, cacheKey); listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); _inputProducer.ProduceResults(wrappedConsumer, producerContext); }
/// <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 <CloseableReference <CloseableImage> > consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; ImageRequest imageRequest = producerContext.ImageRequest; object callerContext = producerContext.CallerContext; // If there's no postprocessor or the postprocessor doesn't // require caching, forward results. IPostprocessor postprocessor = imageRequest.Postprocessor; if (postprocessor == null || postprocessor.PostprocessorCacheKey == null) { _inputProducer.ProduceResults(consumer, producerContext); return; } listener.OnProducerStart(requestId, ProducerName); ICacheKey cacheKey = _cacheKeyFactory.GetPostprocessedBitmapCacheKey( imageRequest, callerContext); CloseableReference <CloseableImage> cachedReference = _memoryCache.Get(cacheKey); var extraMap = default(Dictionary <string, string>); if (cachedReference != null) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "true" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnProgressUpdate(1.0f); consumer.OnNewResult(cachedReference, true); cachedReference.Dispose(); } else { bool isRepeatedProcessor = postprocessor.GetType() == typeof(IRepeatedPostprocessor); IConsumer <CloseableReference <CloseableImage> > cachedConsumer = new CachedPostprocessorConsumer( consumer, cacheKey, isRepeatedProcessor, _memoryCache); extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); _inputProducer.ProduceResults(cachedConsumer, producerContext); } }
/// <summary> /// Test cleanup. /// </summary> public void Dispose() { _mockCloseable.Dispose(); _closeableReference.Dispose(); }
/// <summary> /// Test cleanup. /// </summary> public void Dispose() { _bitmap.Dispose(); _platformBitmapFactory.Dispose(); _bitmapReference.Dispose(); }