/// <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)); }
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 Initialize() { _releaseCallCount = 0; _releaseValues = new List <int>(); _releaser = new ResourceReleaserImpl <int>( v => { ++_releaseCallCount; _releaseValues.Add(v); }); _onExclusivityChangedCallCount = 0; _isExclusive = null; _entryStateObserver = new EntryStateObserverImpl <string>( (v, b) => { ++_onExclusivityChangedCallCount; _isExclusive = b; }); _cacheTrimStrategy = new CacheTrimStrategyImpl(v => _trimRatio); _valueDescriptor = new ValueDescriptorImpl <int>(v => v); _params = new MemoryCacheParams( 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); _platformBitmapFactory = new MockPlatformBitmapFactory(); _bitmap = new SoftwareBitmap(BitmapPixelFormat.Rgba8, 50, 50); _bitmapReference = CloseableReference <SoftwareBitmap> .of( _bitmap, BITMAP_RESOURCE_RELEASER); _cache = new CountingMemoryCache <string, int>( _valueDescriptor, _cacheTrimStrategy, _paramsSupplier, _platformBitmapFactory, true); }
/// <summary> /// Caches the given key-value pair. /// /// <para />Important: the client should use the returned reference /// instead of the original one. It is the caller's responsibility /// to close the returned reference once not needed anymore. /// </summary> /// <returns> /// The new reference to be used, null if the value cannot be cached. /// </returns> public CloseableReference <V> Cache( K key, CloseableReference <V> valueRef, IEntryStateObserver <K> observer) { Preconditions.CheckNotNull(key); Preconditions.CheckNotNull(valueRef); MaybeUpdateCacheParams(); Entry oldExclusive; CloseableReference <V> oldRefToClose = null; CloseableReference <V> clientRef = null; lock (_cacheGate) { // Remove the old item (if any) as it is stale now oldExclusive = _exclusiveEntries.Remove(key); Entry oldEntry = _cachedEntries.Remove(key); if (oldEntry != null) { MakeOrphan(oldEntry); oldRefToClose = ReferenceToClose(oldEntry); } if (CanCacheNewValue(valueRef.Get())) { Entry newEntry = Entry.of(key, valueRef, observer); _cachedEntries.Put(key, newEntry); clientRef = NewClientReference(newEntry); } } CloseableReference <V> .CloseSafely(oldRefToClose); MaybeNotifyExclusiveEntryRemoval(oldExclusive); MaybeEvictEntries(); return(clientRef); }