All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.mahout.cf.taste.impl.common.Cache Maven / Gradle / Ivy

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.mahout.cf.taste.impl.common;

import com.google.common.base.Preconditions;
import org.apache.mahout.cf.taste.common.TasteException;

import java.util.Iterator;

/**
 * 

* An efficient Map-like class which caches values for keys. Values are not "put" into a {@link Cache}; * instead the caller supplies the instance with an implementation of {@link Retriever} which can load the * value for a given key. *

* *

* The cache does not support {@code null} keys. *

* *

* Thanks to Amila Jayasooriya for helping evaluate performance of the rewrite of this class, as part of a * Google Summer of Code 2007 project. *

*/ public final class Cache implements Retriever { private static final Object NULL = new Object(); private final FastMap cache; private final Retriever retriever; /** *

* Creates a new cache based on the given {@link Retriever}. *

* * @param retriever * object which can retrieve values for keys */ public Cache(Retriever retriever) { this(retriever, FastMap.NO_MAX_SIZE); } /** *

* Creates a new cache based on the given {@link Retriever} and with given maximum size. *

* * @param retriever * object which can retrieve values for keys * @param maxEntries * maximum number of entries the cache will store before evicting some */ public Cache(Retriever retriever, int maxEntries) { Preconditions.checkArgument(retriever != null, "retriever is null"); Preconditions.checkArgument(maxEntries >= 1, "maxEntries must be at least 1"); cache = new FastMap(11, maxEntries); this.retriever = retriever; } /** *

* Returns cached value for a key. If it does not exist, it is loaded using a {@link Retriever}. *

* * @param key * cache key * @return value for that key * @throws TasteException * if an exception occurs while retrieving a new cached value */ @Override public V get(K key) throws TasteException { V value; synchronized (cache) { value = cache.get(key); } if (value == null) { return getAndCacheValue(key); } return value == NULL ? null : value; } /** *

* Uncaches any existing value for a given key. *

* * @param key * cache key */ public void remove(K key) { synchronized (cache) { cache.remove(key); } } /** * Clears all cache entries whose key matches the given predicate. */ public void removeKeysMatching(MatchPredicate predicate) { synchronized (cache) { Iterator it = cache.keySet().iterator(); while (it.hasNext()) { K key = it.next(); if (predicate.matches(key)) { it.remove(); } } } } /** * Clears all cache entries whose value matches the given predicate. */ public void removeValueMatching(MatchPredicate predicate) { synchronized (cache) { Iterator it = cache.values().iterator(); while (it.hasNext()) { V value = it.next(); if (predicate.matches(value)) { it.remove(); } } } } /** *

* Clears the cache. *

*/ public void clear() { synchronized (cache) { cache.clear(); } } private V getAndCacheValue(K key) throws TasteException { V value = retriever.get(key); if (value == null) { value = (V) NULL; } synchronized (cache) { cache.put(key, value); } return value; } @Override public String toString() { return "Cache[retriever:" + retriever + ']'; } /** * Used by {#link #removeKeysMatching(Object)} to decide things that are matching. */ public interface MatchPredicate { boolean matches(T thing); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy