private <T extends Serializable> void registerStatistic(String name, StatisticType type, Set<String> tags, Function<EhcacheOffHeapBackingMap<K, OffHeapValueHolder<V>>, T> fn) { registerStatistic(name, type, tags, () -> { EhcacheOffHeapBackingMap<K, OffHeapValueHolder<V>> map = backingMap(); // Returning null means not available. // Do not return -1 because a stat can be negative and it's hard to tell the difference // between -1 meaning unavailable for a stat and for the other one -1 being a right value; return map == null ? null : fn.apply(map); }); }
@Override public void clear() throws StoreAccessException { try { backingMap().clear(); } catch (RuntimeException re) { throw handleException(re); } }
@Override public void invalidateAllWithHash(long hash) { invalidateAllWithHashObserver.begin(); int intHash = HashUtils.longHashToInt(hash); Map<K, OffHeapValueHolder<V>> removed = backingMap().removeAllWithHash(intHash); for (Map.Entry<K, OffHeapValueHolder<V>> entry : removed.entrySet()) { notifyInvalidation(entry.getKey(), entry.getValue()); } invalidateAllWithHashObserver.end(LowerCachingTierOperationsOutcome.InvalidateAllWithHashOutcome.SUCCESS); }
@Override public void invalidate(final K key) throws StoreAccessException { invalidateObserver.begin(); final AtomicBoolean removed = new AtomicBoolean(false); try { backingMap().computeIfPresent(key, (k, present) -> { removed.set(true); notifyInvalidation(key, present); return null; }); if (removed.get()) { invalidateObserver.end(LowerCachingTierOperationsOutcome.InvalidateOutcome.REMOVED); } else { invalidateObserver.end(LowerCachingTierOperationsOutcome.InvalidateOutcome.MISS); } } catch (RuntimeException re) { throw handleException(re); } }
private OffHeapValueHolder<V> newCreateValueHolder(K key, V value, long now, StoreEventSink<K, V> eventSink) { Objects.requireNonNull(value); Duration duration = ExpiryUtils.getExpiryForCreation(key, value, expiry); if(duration.isZero()) { return null; } eventSink.created(key, value); long expirationTime = isExpiryDurationInfinite(duration) ? ValueHolder.NO_EXPIRE : ExpiryUtils.getExpirationMillis(now, duration); return new BasicOffHeapValueHolder<>(backingMap().nextIdFor(key), value, now, expirationTime); }
private OffHeapValueHolder<V> newUpdatedValueHolder(K key, V value, OffHeapValueHolder<V> existing, long now, StoreEventSink<K, V> eventSink) { eventSink.updated(key, existing, value); Duration duration = Duration.ZERO; try { duration = expiry.getExpiryForUpdate(key, existing, value); if (duration != null && duration.isNegative()) { duration = Duration.ZERO; } } catch (RuntimeException re) { LOG.error("Expiry computation caused an exception - Expiry duration will be 0 ", re); } if (Duration.ZERO.equals(duration)) { eventSink.expired(key, () -> value); return null; } if (duration == null) { return new BasicOffHeapValueHolder<>(backingMap().nextIdFor(key), value, now, existing.expirationTime()); } else if (isExpiryDurationInfinite(duration)) { return new BasicOffHeapValueHolder<>(backingMap().nextIdFor(key), value, now, OffHeapValueHolder.NO_EXPIRE); } else { return new BasicOffHeapValueHolder<>(backingMap().nextIdFor(key), value, now, ExpiryUtils.getExpirationMillis(now, duration)); } }
private OffHeapValueHolder<V> computeWithRetry(K key, BiFunction<K, OffHeapValueHolder<V>, OffHeapValueHolder<V>> computeFunction, boolean fault) throws StoreAccessException { OffHeapValueHolder<V> computeResult; try { computeResult = backingMap().compute(key, computeFunction, fault); } catch (OversizeMappingException ex) { try { evictionAdvisor().setSwitchedOn(false); invokeValve(); computeResult = backingMap().compute(key, computeFunction, fault); } catch (OversizeMappingException e) { throw new StoreAccessException("The element with key '" + key + "' is too large to be stored" + " in this offheap store.", e); } catch (RuntimeException e) { throw handleException(e); } finally { evictionAdvisor().setSwitchedOn(true); } } catch (RuntimeException re) { throw handleException(re); } return computeResult; }
final AtomicReference<OffHeapValueHolder<V>> heldValue = new AtomicReference<>(); try { OffHeapValueHolder<V> result = backingMap().computeIfPresent(key, (mappedKey, mappedValue) -> { long now = timeSource.getTimeMillis();
backingMap().computeIfPresent(key, (mappedKey, mappedValue) -> { long now = timeSource.getTimeMillis();
try { backingMap().computeIfPresent(key, (mappedKey, mappedValue) -> {
backingMap().compute(key, computeFunction, false); ValueHolder<V> result = valueHolderAtomicReference.get(); if (result == null) {
@Override public void invalidateAll() throws StoreAccessException { invalidateAllObserver.begin(); StoreAccessException exception = null; long errorCount = 0; for (K k : backingMap().keySet()) { try { invalidate(k); } catch (StoreAccessException e) { errorCount++; if (exception == null) { exception = e; } } } if (exception != null) { invalidateAllObserver.end(LowerCachingTierOperationsOutcome.InvalidateAllOutcome.FAILURE); throw new StoreAccessException("invalidateAll failed - error count: " + errorCount, exception); } invalidateAllObserver.end(LowerCachingTierOperationsOutcome.InvalidateAllOutcome.SUCCESS); }
@Override public ValueHolder<V> getAndFault(K key) throws StoreAccessException { checkKey(key); getAndFaultObserver.begin(); ValueHolder<V> mappedValue; final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink(); try { mappedValue = backingMap().computeIfPresentAndPin(key, (mappedKey, mappedValue1) -> { if(mappedValue1.isExpired(timeSource.getTimeMillis())) { onExpiration(mappedKey, mappedValue1, eventSink); return null; } mappedValue1.detach(); return mappedValue1; }); eventDispatcher.releaseEventSink(eventSink); if (mappedValue == null) { getAndFaultObserver.end(AuthoritativeTierOperationOutcomes.GetAndFaultOutcome.MISS); } else { getAndFaultObserver.end(AuthoritativeTierOperationOutcomes.GetAndFaultOutcome.HIT); } } catch (RuntimeException re) { eventDispatcher.releaseEventSinkAfterFailure(eventSink, re); throw handleException(re); } return mappedValue; }
@Override public boolean flush(K key, final ValueHolder<V> valueFlushed) { checkKey(key); flushObserver.begin(); final StoreEventSink<K, V> eventSink = eventDispatcher.eventSink(); try { boolean result = backingMap().computeIfPinned(key, (k, valuePresent) -> { if (valuePresent.getId() == valueFlushed.getId()) { if (valueFlushed.isExpired(timeSource.getTimeMillis())) { onExpiration(k, valuePresent, eventSink); return null; } valuePresent.updateMetadata(valueFlushed); valuePresent.writeBack(); } return valuePresent; }, valuePresent -> valuePresent.getId() == valueFlushed.getId()); eventDispatcher.releaseEventSink(eventSink); if (result) { flushObserver.end(AuthoritativeTierOperationOutcomes.FlushOutcome.HIT); return true; } else { flushObserver.end(AuthoritativeTierOperationOutcomes.FlushOutcome.MISS); return false; } } catch (RuntimeException re) { eventDispatcher.releaseEventSinkAfterFailure(eventSink, re); throw re; } }
private <T extends Serializable> void registerStatistic(String name, StatisticType type, Set<String> tags, Function<EhcacheOffHeapBackingMap<K, OffHeapValueHolder<V>>, T> fn) { registerStatistic(name, type, tags, () -> { EhcacheOffHeapBackingMap<K, OffHeapValueHolder<V>> map = backingMap(); // Returning null means not available. // Do not return -1 because a stat can be negative and it's hard to tell the difference // between -1 meaning unavailable for a stat and for the other one -1 being a right value; return map == null ? null : fn.apply(map); }); }
@Override public void clear() throws StoreAccessException { try { backingMap().clear(); } catch (RuntimeException re) { throw handleException(re); } }
@Override public void invalidateAllWithHash(long hash) { invalidateAllWithHashObserver.begin(); int intHash = HashUtils.longHashToInt(hash); Map<K, OffHeapValueHolder<V>> removed = backingMap().removeAllWithHash(intHash); for (Map.Entry<K, OffHeapValueHolder<V>> entry : removed.entrySet()) { notifyInvalidation(entry.getKey(), entry.getValue()); } invalidateAllWithHashObserver.end(LowerCachingTierOperationsOutcome.InvalidateAllWithHashOutcome.SUCCESS); }
@Override public void invalidate(final K key) throws StoreAccessException { invalidateObserver.begin(); final AtomicBoolean removed = new AtomicBoolean(false); try { backingMap().computeIfPresent(key, (k, present) -> { removed.set(true); notifyInvalidation(key, present); return null; }); if (removed.get()) { invalidateObserver.end(LowerCachingTierOperationsOutcome.InvalidateOutcome.REMOVED); } else { invalidateObserver.end(LowerCachingTierOperationsOutcome.InvalidateOutcome.MISS); } } catch (RuntimeException re) { throw handleException(re); } }
private OffHeapValueHolder<V> newCreateValueHolder(K key, V value, long now, StoreEventSink<K, V> eventSink) { Objects.requireNonNull(value); Duration duration = ExpiryUtils.getExpiryForCreation(key, value, expiry); if(duration.isZero()) { return null; } eventSink.created(key, value); long expirationTime = isExpiryDurationInfinite(duration) ? ValueHolder.NO_EXPIRE : ExpiryUtils.getExpirationMillis(now, duration); return new BasicOffHeapValueHolder<>(backingMap().nextIdFor(key), value, now, expirationTime); }
@Override public void invalidateAll() throws StoreAccessException { invalidateAllObserver.begin(); StoreAccessException exception = null; long errorCount = 0; for (K k : backingMap().keySet()) { try { invalidate(k); } catch (StoreAccessException e) { errorCount++; if (exception == null) { exception = e; } } } if (exception != null) { invalidateAllObserver.end(LowerCachingTierOperationsOutcome.InvalidateAllOutcome.FAILURE); throw new StoreAccessException("invalidateAll failed - error count: " + errorCount, exception); } invalidateAllObserver.end(LowerCachingTierOperationsOutcome.InvalidateAllOutcome.SUCCESS); }