![JAR search and dependency download from the Maven repository](/logo.png)
com.sri.ai.util.cache.DefaultCacheMap Maven / Gradle / Ivy
/*
* Copyright (c) 2013, SRI International
* All rights reserved.
* Licensed under the The BSD 3-Clause License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://opensource.org/licenses/BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of the aic-util nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.sri.ai.util.cache;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.google.common.annotations.Beta;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheStats;
import com.google.common.collect.ForwardingMap;
import com.google.common.collect.Sets;
import com.sri.ai.util.AICUtilConfiguration;
import com.sri.ai.util.base.NullaryFunction;
/**
* A default implementation for {@link CacheMap} that, upon garbage collection,
* creates a new internal map and moves entries with reachable entries to it,
* discarding all other entries.
*
* If a garbage collection period n
and a reachable object iterator
* maker are provided, then garbage collection happens automatically after every
* n
{@link #put(Object, Object)} operations.
*
* @author braz
* @author oreilly
*/
@Beta
public class DefaultCacheMap extends ForwardingMap implements CacheMap {
// Configuration attributes
private boolean weakKeys = false;
private long maximumSize = NO_MAXIMUM_SIZE;
private NullaryFunction> reachableObjectIteratorMaker = null;
private int garbageCollectionPeriod = NO_GARBAGE_COLLECTION;
// Working attributes
private Cache storage = null;
private Map delegate = null;
private int numberOfPutsSinceLastGarbageCollection = 0;
private Lock garbageCollectLock = new ReentrantLock();
public DefaultCacheMap() {
initStorage();
}
public DefaultCacheMap(boolean weakKeys) {
this(weakKeys, NO_MAXIMUM_SIZE);
}
public DefaultCacheMap(long maximumSize) {
this(false, maximumSize);
}
public DefaultCacheMap(boolean weakKeys, long maximumSize) {
this.weakKeys = weakKeys;
this.maximumSize = maximumSize;
initStorage();
}
public DefaultCacheMap(long maximumSize, NullaryFunction> reachableObjectIteratorMaker, int garbageCollectionPeriod) {
this(false, maximumSize, reachableObjectIteratorMaker, garbageCollectionPeriod);
}
public DefaultCacheMap(boolean weakKeys, long maximumSize, NullaryFunction> reachableObjectIteratorMaker, int garbageCollectionPeriod) {
this.weakKeys = weakKeys;
this.maximumSize = maximumSize;
this.reachableObjectIteratorMaker = reachableObjectIteratorMaker;
this.garbageCollectionPeriod = garbageCollectionPeriod;
initStorage();
}
//
// START-MAP Interface
@Override
public void clear() {
storage.invalidateAll();
storage.cleanUp();
}
@Override
public V get(Object key) {
return storage.getIfPresent(key);
}
@Override
public V put(K key, V value) {
storage.put(key, value);
numberOfPutsSinceLastGarbageCollection++;
checkDoGarbageCollect();
return value;
}
@Override
public void putAll(Map extends K, ? extends V> t) {
storage.putAll(t);
numberOfPutsSinceLastGarbageCollection += t.size();
checkDoGarbageCollect();
}
// END-MAP Interface
//
//
// START-CacheMap
@Override
public void garbageCollect(Iterator reachableObjectsIterator) {
// To ensure we don't garbage collect repeatedly across threads.
if (reachableObjectsIterator != null && garbageCollectLock.tryLock()) {
try {
if (isGarbageCollection() && numberOfPutsSinceLastGarbageCollection >= getGarbageCollectionPeriod()) {
Set reachableObjects = makeTempKeySet();
while (reachableObjectsIterator.hasNext()) {
reachableObjects.add(reachableObjectsIterator.next());
}
delegate.keySet().retainAll(reachableObjects);
storage.cleanUp();
numberOfPutsSinceLastGarbageCollection = 0;
}
} finally {
garbageCollectLock.unlock();
}
}
}
@Override
public int getGarbageCollectionPeriod() {
return garbageCollectionPeriod;
}
@Override
public NullaryFunction> getReachableObjectIteratorMaker() {
return reachableObjectIteratorMaker;
}
@Override
public void setGarbageCollectionPeriod(int period) {
this.garbageCollectionPeriod = period;
}
@Override
public void setReachableObjectIteratorMaker(NullaryFunction> iteratorMaker) {
this.reachableObjectIteratorMaker = iteratorMaker;
}
@Override
public CacheStats stats() {
return storage.stats();
}
// END-CacheMap
//
//
// PROTECTED METHODS
//
@Override
protected Map delegate() {
return delegate;
}
//
// PRIVATE METHODS
//
private void initStorage() {
CacheBuilder
© 2015 - 2025 Weber Informatics LLC | Privacy Policy