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

com.mingri.langhuan.cabinet.container.cache.MultilevelCache Maven / Gradle / Ivy

package com.mingri.langhuan.cabinet.container.cache;

import java.util.function.Function;

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

import com.mingri.langhuan.cabinet.tool.CacheTool;
import com.mingri.langhuan.cabinet.tool.ThreadTool;

/**
 * 多级缓存实现
 * 
 * @author ljl
 *
 */
public class MultilevelCache implements ICache {
	private static final Logger LOGGER = LoggerFactory.getLogger(MultilevelCache.class);

	private MultilevelCache() {
	}

	private ICache firstLevelCache = LocalCache.instance();
	private ICache secondLevelCache;

	private static final String LOCK_PREFIX = "MUILCACHE_LOCK:";
	private int firstLevelCacheMaxTimeout = 120;// 默认120秒

	public ICache getFirstLevelCache() {
		return firstLevelCache;
	}

	public void setFirstLevelCache(ICache firstLevelCache) {
		this.firstLevelCache = firstLevelCache;
		LOGGER.info("开启一级缓存:{}", firstLevelCache);
	}

	public ICache getSecondCache() {
		return secondLevelCache;
	}

	public void setSecondCache(ICache secondCache) {
		this.secondLevelCache = secondCache;
		LOGGER.info("开启二级缓存:{}", secondCache);
	}

	public int getFirstLevelCacheMaxTimeout() {
		return firstLevelCacheMaxTimeout;
	}

	public void setFirstLevelCacheMaxTimeout(int firstLevelCacheMaxTimeout) {
		this.firstLevelCacheMaxTimeout = firstLevelCacheMaxTimeout;
	}

	public void put(String key, Object value) {
		put(key, value, 0);
	}

	public void put(String key, Object value, int timeOutSecond) {
		if (secondLevelCache != null) {
			secondLevelCache.put(key, value, timeOutSecond);
			firstLevelCache.put(key, value, cmpFirstCacheTimeOutSecond(timeOutSecond));
		} else {
			firstLevelCache.put(key, value, timeOutSecond);
		}
	}

	/**
	 * 提供数据,并缓存
	 * 
	 * @param       返回的对象类型
	 * @param key      缓存键
	 * @param mappingFunction 缓存值提供者
	 * @return 返回缓存的对象
	 */
	public  T computeIfAbsent(String key, Function mappingFunction) {
		return computeIfAbsent(key, 0, mappingFunction);
	}

	/**
	 * 提供数据,并缓存一定的时间
	 * 
	 * @param            返回的对象类型
	 * @param key           缓存键
	 * @param timeOutSecond 缓存超时时间(秒)
	 * @param mappingFunction      缓存数据计算者
	 * @return 返回缓存的对象
	 */
	public  T computeIfAbsent(String key, int timeOutSecond, Function mappingFunction) {
		T data = firstLevelCache.get(key);
		if (data == null && secondLevelCache != null) {
			data = secondLevelCache.get(key);
		}
		if (data != null) {
			return data;
		}
		synchronized (ThreadTool.buildLock(LOCK_PREFIX, key)) {
			data = firstLevelCache.get(key);
			if (data == null && secondLevelCache != null) {
				data = secondLevelCache.get(key);
			}
			if (data != null) {
				return data;
			}
			data = mappingFunction.apply(key);
			if (secondLevelCache != null) {
				secondLevelCache.put(key, data, timeOutSecond);
				firstLevelCache.put(key, data, cmpFirstCacheTimeOutSecond(timeOutSecond));
			} else {
				firstLevelCache.put(key, data, timeOutSecond);
			}

		}
		return data;
	}

	@SuppressWarnings("unchecked")
	public  T removeAndGet(String key) {
		T data = null;
		if (secondLevelCache != null) {
			data = secondLevelCache.removeAndGet(key);
		}
		T data2 = firstLevelCache.removeAndGet(key);
		if (data == null) {
			data = data2;
		}
		return (T) CacheTool.getSrcVal(data);
	}

	public void remove(String key) {
		if (secondLevelCache != null) {
			secondLevelCache.remove(key);
		}
		firstLevelCache.remove(key);
	}

	@SuppressWarnings("unchecked")
	public  T get(String key) {
		T data = firstLevelCache.get(key);
		if (data == null && secondLevelCache != null) {
			data = secondLevelCache.get(key);
		}
		return (T) CacheTool.getSrcVal(data);
	}

	public void expire(String key, int timeOutSecond) {
		firstLevelCache.expire(key, cmpFirstCacheTimeOutSecond(timeOutSecond));
		if (secondLevelCache != null) {
			secondLevelCache.expire(key, timeOutSecond);
		}
	}

	public boolean hashKey(String key) {
		boolean flag = firstLevelCache.hasKey(key);
		if (!flag && secondLevelCache != null) {
			flag = secondLevelCache.hasKey(key);
		}
		return flag;
	}

	private int cmpFirstCacheTimeOutSecond(int timeOutSecond) {
		if (timeOutSecond < 1 || timeOutSecond > firstLevelCacheMaxTimeout) {
			return firstLevelCacheMaxTimeout;
		}
		return timeOutSecond;
	}

	@Override
	public void leftPush(String key, Object value) {
		firstLevelCache.leftPush(key, value);
		if (secondLevelCache != null) {
			secondLevelCache.leftPush(key, value);
		}
	}

	@Override
	public void rightPush(String key, Object value) {
		firstLevelCache.rightPush(key, value);
		if (secondLevelCache != null) {
			secondLevelCache.rightPush(key, value);
		}
	}

	@Override
	public  T rightPop(String key) {
		T data = firstLevelCache.rightPop(key);
		if (data == null && secondLevelCache != null) {
			data = secondLevelCache.rightPop(key);
		}
		return data;
	}

	@Override
	public  T leftPop(String key) {
		T data = firstLevelCache.leftPop(key);
		if (data == null && secondLevelCache != null) {
			data = secondLevelCache.leftPop(key);
		}
		return data;
	}

	@Override
	public  T putIfAbsent(String key, Object value) {
		return putIfAbsent(key, value, 0);
	}

	@SuppressWarnings("unchecked")
	@Override
	public  T putIfAbsent(String key, Object value, int timeOutSecond) {
		Object data = firstLevelCache.putIfAbsent(key, value, timeOutSecond);
		if (data == null && secondLevelCache != null) {
			secondLevelCache.putIfAbsent(key, value, timeOutSecond);
		}
		return (T) data;
	}

	@Override
	public boolean hasKey(String key) {
		return firstLevelCache.hasKey(key) || (secondLevelCache != null && secondLevelCache.hasKey(key));
	}

	@Override
	public long size() {
		if (secondLevelCache != null) {
			return secondLevelCache.size();
		}
		return firstLevelCache.size();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy