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

com.alicp.jetcache.SimpleCacheManager Maven / Gradle / Ivy

The newest version!
/**
 * Created on 2019/2/1.
 */
package com.alicp.jetcache;

import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.embedded.EmbeddedCacheBuilder;
import com.alicp.jetcache.external.ExternalCacheBuilder;
import com.alicp.jetcache.support.BroadcastManager;
import com.alicp.jetcache.template.CacheBuilderTemplate;
import com.alicp.jetcache.template.CacheMonitorInstaller;
import com.alicp.jetcache.template.QuickConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * @author huangli
 */
public class SimpleCacheManager implements CacheManager, AutoCloseable {

    private static final boolean DEFAULT_CACHE_NULL_VALUE = false;

    private static final Logger logger = LoggerFactory.getLogger(SimpleCacheManager.class);

    // area -> cacheName -> Cache
    private final ConcurrentHashMap> caches = new ConcurrentHashMap<>();

    private final ConcurrentHashMap broadcastManagers = new ConcurrentHashMap();

    private CacheBuilderTemplate cacheBuilderTemplate;

    public SimpleCacheManager() {
    }

    @Override
    public void close() {
        broadcastManagers.forEach((area, bm) -> {
            try {
                bm.close();
            } catch (Exception e) {
                logger.error("error during close broadcast manager", e);
            }
        });
        broadcastManagers.clear();
        caches.forEach((area, areaMap) -> {
            areaMap.forEach((cacheName, cache) -> {
                try {
                    cache.close();
                } catch (Exception e) {
                    logger.error("error during close Cache", e);
                }
            });
        });
        caches.clear();
    }

    private ConcurrentHashMap getCachesByArea(String area) {
        return caches.computeIfAbsent(area, (key) -> new ConcurrentHashMap<>());
    }

    @Override
    public Cache getCache(String area, String cacheName) {
        ConcurrentHashMap areaMap = getCachesByArea(area);
        return areaMap.get(cacheName);
    }

    @Override
    public void putCache(String area, String cacheName, Cache cache) {
        ConcurrentHashMap areaMap = getCachesByArea(area);
        areaMap.put(cacheName, cache);
    }

    @Override
    public BroadcastManager getBroadcastManager(String area) {
        return broadcastManagers.get(area);
    }

    @Override
    public void putBroadcastManager(String area, BroadcastManager broadcastManager) {
        broadcastManagers.put(area, broadcastManager);
    }

    public CacheBuilderTemplate getCacheBuilderTemplate() {
        return cacheBuilderTemplate;
    }

    public void setCacheBuilderTemplate(CacheBuilderTemplate cacheBuilderTemplate) {
        this.cacheBuilderTemplate = cacheBuilderTemplate;
    }

    @Override
    public  Cache getOrCreateCache(QuickConfig config) {
        if (cacheBuilderTemplate == null) {
            throw new IllegalStateException("cacheBuilderTemplate not set");
        }
        Objects.requireNonNull(config.getArea());
        Objects.requireNonNull(config.getName());
        ConcurrentHashMap m = getCachesByArea(config.getArea());
        Cache c = m.get(config.getName());
        if (c != null) {
            return c;
        }
        return m.computeIfAbsent(config.getName(), n -> create(config));
    }

    private Cache create(QuickConfig config) {
        Cache cache;
        if (config.getCacheType() == null || config.getCacheType() == CacheType.REMOTE) {
            cache = buildRemote(config);
        } else if (config.getCacheType() == CacheType.LOCAL) {
            cache = buildLocal(config);
        } else {
            Cache local = buildLocal(config);
            Cache remote = buildRemote(config);


            boolean useExpireOfSubCache = config.getLocalExpire() != null;
            cache = MultiLevelCacheBuilder.createMultiLevelCacheBuilder()
                    .expireAfterWrite(remote.config().getExpireAfterWriteInMillis(), TimeUnit.MILLISECONDS)
                    .addCache(local, remote)
                    .useExpireOfSubCache(useExpireOfSubCache)
                    .cacheNullValue(config.getCacheNullValue() != null ?
                            config.getCacheNullValue() : DEFAULT_CACHE_NULL_VALUE)
                    .buildCache();
        }
        if (config.getRefreshPolicy() != null) {
            cache = new RefreshCache(cache);
        } else if (config.getLoader() != null) {
            cache = new LoadingCache(cache);
        }
        cache.config().setRefreshPolicy(config.getRefreshPolicy());
        cache.config().setLoader(config.getLoader());


        boolean protect = config.getPenetrationProtect() != null ? config.getPenetrationProtect()
                : cacheBuilderTemplate.isPenetrationProtect();
        cache.config().setCachePenetrationProtect(protect);
        cache.config().setPenetrationProtectTimeout(config.getPenetrationProtectTimeout());

        for (CacheMonitorInstaller i : cacheBuilderTemplate.getCacheMonitorInstallers()) {
            i.addMonitors(this, cache, config);
        }
        return cache;
    }

    private Cache buildRemote(QuickConfig config) {
        ExternalCacheBuilder cacheBuilder = (ExternalCacheBuilder) cacheBuilderTemplate
                .getCacheBuilder(1, config.getArea());
        if (cacheBuilder == null) {
            throw new CacheConfigException("no remote cache builder: " + config.getArea());
        }

        if (config.getExpire() != null && config.getExpire().toMillis() > 0) {
            cacheBuilder.expireAfterWrite(config.getExpire().toMillis(), TimeUnit.MILLISECONDS);
        }

        String prefix;
        if (config.getUseAreaInPrefix() != null && config.getUseAreaInPrefix()) {
            prefix = config.getArea() + "_" + config.getName();
        } else {
            prefix = config.getName();
        }
        if (cacheBuilder.getConfig().getKeyPrefixSupplier() != null) {
            Supplier supplier = cacheBuilder.getConfig().getKeyPrefixSupplier();
            cacheBuilder.setKeyPrefixSupplier(() -> supplier.get() + prefix);
        } else {
            cacheBuilder.setKeyPrefix(prefix);
        }

        if (config.getKeyConvertor() != null) {
            cacheBuilder.getConfig().setKeyConvertor(config.getKeyConvertor());
        }
        if (config.getValueEncoder() != null) {
            cacheBuilder.getConfig().setValueEncoder(config.getValueEncoder());
        }
        if (config.getValueDecoder() != null) {
            cacheBuilder.getConfig().setValueDecoder(config.getValueDecoder());
        }

        cacheBuilder.setCacheNullValue(config.getCacheNullValue() != null ?
                config.getCacheNullValue() : DEFAULT_CACHE_NULL_VALUE);
        return cacheBuilder.buildCache();
    }

    private Cache buildLocal(QuickConfig config) {
        EmbeddedCacheBuilder cacheBuilder = (EmbeddedCacheBuilder) cacheBuilderTemplate.getCacheBuilder(0, config.getArea());
        if (cacheBuilder == null) {
            throw new CacheConfigException("no local cache builder: " + config.getArea());
        }

        if (config.getLocalLimit() != null && config.getLocalLimit() > 0) {
            cacheBuilder.setLimit(config.getLocalLimit());
        }
        if (config.getCacheType() == CacheType.BOTH &&
                config.getLocalExpire() != null && config.getLocalExpire().toMillis() > 0) {
            cacheBuilder.expireAfterWrite(config.getLocalExpire().toMillis(), TimeUnit.MILLISECONDS);
        } else if (config.getExpire() != null && config.getExpire().toMillis() > 0) {
            cacheBuilder.expireAfterWrite(config.getExpire().toMillis(), TimeUnit.MILLISECONDS);
        }
        if (config.getKeyConvertor() != null) {
            cacheBuilder.getConfig().setKeyConvertor(config.getKeyConvertor());
        }
        cacheBuilder.setCacheNullValue(config.getCacheNullValue() != null ?
                config.getCacheNullValue() : DEFAULT_CACHE_NULL_VALUE);
        return cacheBuilder.buildCache();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy