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

com.adobe.cq.social.srp.internal.AbstractCache Maven / Gradle / Ivy

There is a newer version: 6.5.21
Show newest version
/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2012 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/
package com.adobe.cq.social.srp.internal;

import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

/**
 * A simple request cache.
 * @param  the lookup key
 * @param  the type of the items in the cache.
 */
public abstract class AbstractCache {
    /** by default, use caching. */
    public static final boolean DEFAULT_CACHE_ON = true;
    /** by default leave items in the cache this long. */
    public static final long DEFAULT_CACHE_TTL = 5000;
    /** default initial cache size */
    public static final int DEFAULT_START_CACHE_SIZE = 100;
    /** by default, allow this many items in the cache. */
    public static final int DEFAULT_MAX_CACHE_SIZE = 2500;
    /** default concurrency level */
    public static final int DEFAULT_CONCURRENCY_LEVEL = 4;

    private static final Logger LOG = LoggerFactory.getLogger(AbstractCache.class);
    private static final long serialVersionUID = 1L;

    private boolean useCache = DEFAULT_CACHE_ON;

    private Cache> cache;

    /**
     * @param concurrencyLevel cache concurreny level
     * @param cacheStartSize starting cache size
     * @param cacheMaxSize the initial size of the cache.
     * @param ttl expiration time for cache entries in milliseconds
     */
    public AbstractCache(final int concurrencyLevel, final int cacheStartSize, final int cacheMaxSize, final long ttl) {
        this.cache =
            CacheBuilder.newBuilder().concurrencyLevel(concurrencyLevel).initialCapacity(cacheStartSize)
                .maximumSize(cacheMaxSize).expireAfterWrite(ttl, TimeUnit.MILLISECONDS).build();
    }

    public AbstractCache() {
        this.cache =
            CacheBuilder.newBuilder().concurrencyLevel(DEFAULT_CONCURRENCY_LEVEL)
                .initialCapacity(DEFAULT_START_CACHE_SIZE).maximumSize(DEFAULT_MAX_CACHE_SIZE)
                .expireAfterWrite(DEFAULT_CACHE_TTL, TimeUnit.MILLISECONDS).build();
    }

    public void put(final Y key, final CacheEntry doc) {
        // doc can't be null because guava cache doesn't support null values. However, this is just a safeguard here
        // because CacheEntry should never by null.
        if (key == null || doc == null) {
            return;
        }

        LOG.debug("Updating cache for {}: {}", key, doc.get());

        cache.put(key, doc);
    }

    public void remove(final Object key) {
        cache.invalidate(key);
    }

    public void removeAll(final Iterable keys) {
        cache.invalidateAll(keys);
    }

    /**
     * merge the doc into the current cached item, if it exists. How you merge depends on the type of the cache entry,
     * thus this is abstract.
     * @param key the key into the cache
     * @param doc the changed items
     * @param returnedResult the returned result
     */
    public abstract void merge(final Y key, final X doc, final X returnedResult);

    public CacheEntry get(final Object key) {
        if (!useCache) {
            LOG.debug("Cache not used for: {}", key);
            return null;
        }

        final CacheEntry doc = cache.getIfPresent(key);

        if (LOG.isDebugEnabled()) {
            if (doc != null) {
                LOG.debug("Cache --HIT--: {}", key);
            } else {
                LOG.debug("Cache MISS or EXPIRED: {}", key);
            }
        }

        return doc;
    }

    /**
     * Enables or disables the cache.
     * @param mode true if the cache should be enabled. False otherwise.
     */
    public void setCacheMode(final boolean mode) {
        this.useCache = mode;
        LOG.debug("Cache is on?: {}", mode);
    }

    public Set keySet() {
        return cache.asMap().keySet();
    }

    public void clear() {
        cache.invalidateAll();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy