@Test public void testInlineEvictionNotified() { PoolAccessor onHeapAccessor = mock(PoolAccessor.class); when(onHeapAccessor.add(eq("key"), any(DiskStorageFactory.DiskSubstitute.class), any(HashEntry.class), eq(false))).thenReturn(-1L); RegisteredEventListeners cacheEventNotificationService = new RegisteredEventListeners(mock(Ehcache.class), null); CacheEventListener listener = mock(CacheEventListener.class); cacheEventNotificationService.registerListener(listener); OperationObserver<CacheOperationOutcomes.EvictionOutcome> evictionObserver = mock(OperationObserver.class); Segment segment = new Segment(10, .95f, mock(DiskStorageFactory.class), mock(CacheConfiguration.class), onHeapAccessor, mock(PoolAccessor.class), cacheEventNotificationService, evictionObserver); Element element = new Element("key", "value"); segment.put("key", 12, element, false, false); verify(listener).notifyElementEvicted(any(Ehcache.class), eq(element)); verify(evictionObserver).end(CacheOperationOutcomes.EvictionOutcome.SUCCESS); }
Element put(Object key, int hash, Element element, boolean onlyIfAbsent, boolean faulted) { boolean installed = false; DiskSubstitute encoded = disk.create(element); final long incomingHeapSize = onHeapPoolAccessor.add(key, encoded, NULL_HASH_ENTRY, cachePinned || faulted); if (incomingHeapSize < 0) { LOG.debug("put failed to add on heap"); evictionObserver.end(EvictionOutcome.SUCCESS); cacheEventNotificationService.notifyElementEvicted(element, false); return null; } else { LOG.debug("put added {} on heap", incomingHeapSize); encoded.onHeapSize = incomingHeapSize; } writeLock().lock(); try { if (count + 1 > threshold) { rehash(); } HashEntry[] tab = table; int index = hash & (tab.length - 1); HashEntry first = tab[index]; HashEntry e = first; while (e != null && (e.hash != hash || !key.equals(e.key))) { e = e.next; } Element oldElement; if (e != null) { DiskSubstitute onDiskSubstitute = e.element; if (!onlyIfAbsent) { e.element = encoded; installed = true; oldElement = decode(onDiskSubstitute); free(onDiskSubstitute); final long existingHeapSize = onHeapPoolAccessor.delete(onDiskSubstitute.onHeapSize); LOG.debug("put updated, deleted {} on heap", existingHeapSize); if (onDiskSubstitute instanceof DiskStorageFactory.DiskMarker) { final long existingDiskSize = onDiskPoolAccessor.delete(((DiskStorageFactory.DiskMarker) onDiskSubstitute).getSize()); LOG.debug("put updated, deleted {} on disk", existingDiskSize); } e.faulted.set(faulted); cacheEventNotificationService.notifyElementUpdatedOrdered(oldElement, element); } else { oldElement = decode(onDiskSubstitute); free(encoded); final long outgoingHeapSize = onHeapPoolAccessor.delete(encoded.onHeapSize); LOG.debug("put if absent failed, deleted {} on heap", outgoingHeapSize); } } else { oldElement = null; ++modCount; tab[index] = new HashEntry(key, hash, first, encoded, new AtomicBoolean(faulted)); installed = true; count = count + 1; cacheEventNotificationService.notifyElementPutOrdered(element); } return oldElement; } finally { writeLock().unlock(); if (installed) { encoded.installed(); } } }
Segment extends ReentrantReadWriteLock { Element put(Object key, int hash, Element element, boolean onlyIfAbsent, boolean faulted) { boolean installed = false; DiskSubstitute encoded = disk.create(element); final long incomingHeapSize = onHeapPoolAccessor.add(key, encoded, NULL_HASH_ENTRY, cachePinned || faulted); if (incomingHeapSize < 0) { LOG.debug("put failed to add on heap"); evictionObserver.end(EvictionOutcome.SUCCESS); cacheEventNotificationService.notifyElementEvicted(element, false); return null; } else { LOG.debug("put added {} on heap", incomingHeapSize); encoded.onHeapSize = incomingHeapSize; } writeLock().lock(); try { if (count + 1 > threshold) { rehash(); } HashEntry[] tab = table; int index = hash & (tab.length - 1); HashEntry first = tab[index]; HashEntry e = first; while (e != null && (e.hash != hash || !key.equals(e.key))) { e = e.next; } Element oldElement; if (e != null) { DiskSubstitute onDiskSubstitute = e.element; if (!onlyIfAbsent) { e.element = encoded; installed = true; oldElement = decode(onDiskSubstitute); free(onDiskSubstitute); final long existingHeapSize = onHeapPoolAccessor.delete(onDiskSubstitute.onHeapSize); LOG.debug("put updated, deleted {} on heap", existingHeapSize); if (onDiskSubstitute instanceof DiskStorageFactory.DiskMarker) { final long existingDiskSize = onDiskPoolAccessor.delete(((DiskStorageFactory.DiskMarker) onDiskSubstitute).getSize()); LOG.debug("put updated, deleted {} on disk", existingDiskSize); } e.faulted.set(faulted); cacheEventNotificationService.notifyElementUpdatedOrdered(oldElement, element); } else { oldElement = decode(onDiskSubstitute); free(encoded); final long outgoingHeapSize = onHeapPoolAccessor.delete(encoded.onHeapSize); LOG.debug("put if absent failed, deleted {} on heap", outgoingHeapSize); } } else { oldElement = null; ++modCount; tab[index] = new HashEntry(key, hash, first, encoded, new AtomicBoolean(faulted)); installed = true; count = count + 1; cacheEventNotificationService.notifyElementPutOrdered(element); } return oldElement; } finally { writeLock().unlock(); if (installed) { encoded.installed(); } } } }
Segment extends ReentrantReadWriteLock { Element put(Object key, int hash, Element element, boolean onlyIfAbsent, boolean faulted) { boolean installed = false; DiskSubstitute encoded = disk.create(element); final long incomingHeapSize = onHeapPoolAccessor.add(key, encoded, NULL_HASH_ENTRY, cachePinned || faulted); if (incomingHeapSize < 0) { LOG.debug("put failed to add on heap"); evictionObserver.end(EvictionOutcome.SUCCESS); cacheEventNotificationService.notifyElementEvicted(element, false); return null; } else { LOG.debug("put added {} on heap", incomingHeapSize); encoded.onHeapSize = incomingHeapSize; } writeLock().lock(); try { if (count + 1 > threshold) { rehash(); } HashEntry[] tab = table; int index = hash & (tab.length - 1); HashEntry first = tab[index]; HashEntry e = first; while (e != null && (e.hash != hash || !key.equals(e.key))) { e = e.next; } Element oldElement; if (e != null) { DiskSubstitute onDiskSubstitute = e.element; if (!onlyIfAbsent) { e.element = encoded; installed = true; oldElement = decode(onDiskSubstitute); free(onDiskSubstitute); final long existingHeapSize = onHeapPoolAccessor.delete(onDiskSubstitute.onHeapSize); LOG.debug("put updated, deleted {} on heap", existingHeapSize); if (onDiskSubstitute instanceof DiskStorageFactory.DiskMarker) { final long existingDiskSize = onDiskPoolAccessor.delete(((DiskStorageFactory.DiskMarker) onDiskSubstitute).getSize()); LOG.debug("put updated, deleted {} on disk", existingDiskSize); } e.faulted.set(faulted); cacheEventNotificationService.notifyElementUpdatedOrdered(oldElement, element); } else { oldElement = decode(onDiskSubstitute); free(encoded); final long outgoingHeapSize = onHeapPoolAccessor.delete(encoded.onHeapSize); LOG.debug("put if absent failed, deleted {} on heap", outgoingHeapSize); } } else { oldElement = null; ++modCount; tab[index] = new HashEntry(key, hash, first, encoded, new AtomicBoolean(faulted)); installed = true; count = count + 1; cacheEventNotificationService.notifyElementPutOrdered(element); } return oldElement; } finally { writeLock().unlock(); if (installed) { encoded.installed(); } } } Segment(int initialCapacity, float loadFactor, DiskStorageFactory primary,
                   CacheConfiguration cacheConfiguration,
                   PoolAccessor onHeapPoolAccessor, PoolAccessor onDiskPoolAccessor,
                   RegisteredEventListeners cacheEventNotificationService,
                   OperationObserver<EvictionOutcome> evictionObserver); }
Segment extends ReentrantReadWriteLock { Element put(Object key, int hash, Element element, boolean onlyIfAbsent, boolean faulted) { boolean installed = false; DiskSubstitute encoded = disk.create(element); final long incomingHeapSize = onHeapPoolAccessor.add(key, encoded, NULL_HASH_ENTRY, cachePinned || faulted); if (incomingHeapSize < 0) { LOG.debug("put failed to add on heap"); evictionObserver.end(EvictionOutcome.SUCCESS); cacheEventNotificationService.notifyElementEvicted(element, false); return null; } else { LOG.debug("put added {} on heap", incomingHeapSize); encoded.onHeapSize = incomingHeapSize; } writeLock().lock(); try { if (count + 1 > threshold) { rehash(); } HashEntry[] tab = table; int index = hash & (tab.length - 1); HashEntry first = tab[index]; HashEntry e = first; while (e != null && (e.hash != hash || !key.equals(e.key))) { e = e.next; } Element oldElement; if (e != null) { DiskSubstitute onDiskSubstitute = e.element; if (!onlyIfAbsent) { e.element = encoded; installed = true; oldElement = decode(onDiskSubstitute); free(onDiskSubstitute); final long existingHeapSize = onHeapPoolAccessor.delete(onDiskSubstitute.onHeapSize); LOG.debug("put updated, deleted {} on heap", existingHeapSize); if (onDiskSubstitute instanceof DiskStorageFactory.DiskMarker) { final long existingDiskSize = onDiskPoolAccessor.delete(((DiskStorageFactory.DiskMarker) onDiskSubstitute).getSize()); LOG.debug("put updated, deleted {} on disk", existingDiskSize); } e.faulted.set(faulted); cacheEventNotificationService.notifyElementUpdatedOrdered(oldElement, element); } else { oldElement = decode(onDiskSubstitute); free(encoded); final long outgoingHeapSize = onHeapPoolAccessor.delete(encoded.onHeapSize); LOG.debug("put if absent failed, deleted {} on heap", outgoingHeapSize); } } else { oldElement = null; ++modCount; tab[index] = new HashEntry(key, hash, first, encoded, new AtomicBoolean(faulted)); installed = true; count = count + 1; cacheEventNotificationService.notifyElementPutOrdered(element); } return oldElement; } finally { writeLock().unlock(); if (installed) { encoded.installed(); } } } Segment(int initialCapacity, float loadFactor, DiskStorageFactory primary,
                   CacheConfiguration cacheConfiguration,
                   PoolAccessor onHeapPoolAccessor, PoolAccessor onDiskPoolAccessor,
                   RegisteredEventListeners cacheEventNotificationService,
                   OperationObserver<EvictionOutcome> evictionObserver); @Override String toString(); boolean isFaulted(final int hash, final Object key); }
Segment extends ReentrantReadWriteLock { Element put(Object key, int hash, Element element, boolean onlyIfAbsent, boolean faulted) { boolean installed = false; DiskSubstitute encoded = disk.create(element); final long incomingHeapSize = onHeapPoolAccessor.add(key, encoded, NULL_HASH_ENTRY, cachePinned || faulted); if (incomingHeapSize < 0) { LOG.debug("put failed to add on heap"); evictionObserver.end(EvictionOutcome.SUCCESS); cacheEventNotificationService.notifyElementEvicted(element, false); return null; } else { LOG.debug("put added {} on heap", incomingHeapSize); encoded.onHeapSize = incomingHeapSize; } writeLock().lock(); try { if (count + 1 > threshold) { rehash(); } HashEntry[] tab = table; int index = hash & (tab.length - 1); HashEntry first = tab[index]; HashEntry e = first; while (e != null && (e.hash != hash || !key.equals(e.key))) { e = e.next; } Element oldElement; if (e != null) { DiskSubstitute onDiskSubstitute = e.element; if (!onlyIfAbsent) { e.element = encoded; installed = true; oldElement = decode(onDiskSubstitute); free(onDiskSubstitute); final long existingHeapSize = onHeapPoolAccessor.delete(onDiskSubstitute.onHeapSize); LOG.debug("put updated, deleted {} on heap", existingHeapSize); if (onDiskSubstitute instanceof DiskStorageFactory.DiskMarker) { final long existingDiskSize = onDiskPoolAccessor.delete(((DiskStorageFactory.DiskMarker) onDiskSubstitute).getSize()); LOG.debug("put updated, deleted {} on disk", existingDiskSize); } e.faulted.set(faulted); cacheEventNotificationService.notifyElementUpdatedOrdered(oldElement, element); } else { oldElement = decode(onDiskSubstitute); free(encoded); final long outgoingHeapSize = onHeapPoolAccessor.delete(encoded.onHeapSize); LOG.debug("put if absent failed, deleted {} on heap", outgoingHeapSize); } } else { oldElement = null; ++modCount; tab[index] = new HashEntry(key, hash, first, encoded, new AtomicBoolean(faulted)); installed = true; count = count + 1; cacheEventNotificationService.notifyElementPutOrdered(element); } return oldElement; } finally { writeLock().unlock(); if (installed) { encoded.installed(); } } } Segment(int initialCapacity, float loadFactor, DiskStorageFactory primary,
                   CacheConfiguration cacheConfiguration,
                   PoolAccessor onHeapPoolAccessor, PoolAccessor onDiskPoolAccessor,
                   RegisteredEventListeners cacheEventNotificationService,
                   OperationObserver<EvictionOutcome> evictionObserver); @Override String toString(); boolean isFaulted(final int hash, final Object key);  }