/** * <p> * Wraps another matcher but caches the result of previously matched elements. Caching can be important if a * matcher requires expensive calculations. * </p> * <p> * <b>Warning</b>: The supplied map can however introduce a memory leak as the matched elements are stored within the map. * It is therefore important to dereference this matcher at some point or to regularly evict entries from the supplied map. * </p> * * @param matcher The actual matcher for which the results are cached. * @param map The map for storing results of previously matched elements. * @param <T> The type of the matched object. * @return A matcher that stores the results of a previous matching in the supplied map. */ public static <T> ElementMatcher.Junction<T> cached(ElementMatcher<? super T> matcher, ConcurrentMap<? super T, Boolean> map) { return new CachingMatcher<T>(matcher, map); }
/** * {@inheritDoc} */ public boolean matches(T target) { Boolean cached = map.get(target); if (cached == null) { cached = onCacheMiss(target); } return cached; }
/** * {@inheritDoc} */ protected boolean onCacheMiss(S target) { if (map.size() >= evictionSize) { Iterator<?> iterator = map.entrySet().iterator(); iterator.next(); iterator.remove(); } return super.onCacheMiss(target); } }