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

com.yuweix.kuafu.data.cache.redis.jedis.JedisClusterCache Maven / Gradle / Ivy

The newest version!
package com.yuweix.kuafu.data.cache.redis.jedis;


import java.util.*;

import com.yuweix.kuafu.data.cache.AbstractCache;
import com.yuweix.kuafu.data.cache.MessageHandler;
import com.yuweix.kuafu.data.cache.redis.RedisCache;

import com.yuweix.kuafu.data.serializer.Serializer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPubSub;


/**
 * @author yuwei
 */
public class JedisClusterCache extends AbstractCache implements RedisCache {
	protected JedisCluster jedisCluster;
	protected Serializer serializer;


	public JedisClusterCache(Serializer serializer) {
		this.serializer = serializer;
	}


	public void setJedisCluster(JedisCluster jedisCluster) {
		this.jedisCluster = jedisCluster;
	}

	public void setSerializer(Serializer serializer) {
		this.serializer = serializer;
	}

	@Override
	public void subscribe(final String channel, final MessageHandler handler) {
		subscribe(Collections.singletonList(channel), handler);
	}

	@Override
	public void subscribe(List channels, final MessageHandler handler) {
		new Thread(() -> jedisCluster.subscribe(new JedisPubSub() {
			@Override
			public void onMessage(String channel, String message) {
				handler.handle(channel, message);
			}
		}, channels.toArray(new String[0]))).start();
	}

	@Override
	public void publish(String channel, String message) {
		jedisCluster.publish(channel, message);
	}

	@Override
	public boolean contains(String key) {
		Boolean exists = jedisCluster.exists(key);
		return exists != null && exists;
	}

	@Override
	public void expire(String key, long timeout) {
		jedisCluster.expire(key, (int) timeout);
	}

	@Override
	public  boolean put(String key, T value, long timeout) {
		if (timeout <= 0) {
			throw new RuntimeException("Invalid parameter[timeout].");
		}

		String res = jedisCluster.setex(key, (int) timeout, serializer.serialize(value));
		return "OK".equalsIgnoreCase(res);
	}

	@Override
	public T get(String key) {
		return serializer.deserialize(jedisCluster.get(key));
	}

	@Override
	public void remove(String key) {
		jedisCluster.del(key);
	}

	@Override
	public boolean hset(String key, String field, T value, long timeout) {
		jedisCluster.hset(key, field, serializer.serialize(value));
		jedisCluster.expire(key, (int) timeout);
		return true;
	}

	@Override
	public boolean hmset(String key, Map entries, long timeout) {
		if (entries == null || entries.isEmpty()) {
			return true;
		}
		Map strMap = new HashMap<>();
		for (Map.Entry entry: entries.entrySet()) {
			strMap.put(entry.getKey(), serializer.serialize(entry.getValue()));
		}
		jedisCluster.hmset(key, strMap);
		jedisCluster.expire(key, (int) timeout);
		return true;
	}

	@Override
	public T hget(String key, String field) {
		return serializer.deserialize(jedisCluster.hget(key, field));
	}

	@Override
	public Map hgetAll(String key) {
		Map strMap = jedisCluster.hgetAll(key);
		Map resMap = new HashMap<>();
		if (strMap == null || strMap.isEmpty()) {
			return resMap;
		}
		for (Map.Entry strEntry: strMap.entrySet()) {
			resMap.put(strEntry.getKey(), serializer.deserialize(strEntry.getValue()));
		}
		return resMap;
	}

	@Override
	public void remove(String key, String field) {
		jedisCluster.hdel(key, field);
	}

	@Override
	public boolean lpush(String key, T value, long timeout) {
		jedisCluster.lpush(key, serializer.serialize(value));
		jedisCluster.expire(key, (int) timeout);
		return true;
	}

	@Override
	public boolean lpush(String key, List valList, long timeout) {
		if (valList == null || valList.size() <= 0) {
			return true;
		}
		List strList = new ArrayList<>();
		for (T t: valList) {
			strList.add(serializer.serialize(t));
		}
		jedisCluster.lpush(key, strList.toArray(new String[0]));
		jedisCluster.expire(key, (int) timeout);
		return true;
	}

	@Override
	public boolean rpush(String key, T value, long timeout) {
		jedisCluster.rpush(key, serializer.serialize(value));
		jedisCluster.expire(key, (int) timeout);
		return true;
	}

	@Override
	public boolean rpush(String key, List valList, long timeout) {
		if (valList == null || valList.size() <= 0) {
			return true;
		}
		List strList = new ArrayList<>();
		for (T t: valList) {
			strList.add(serializer.serialize(t));
		}
		jedisCluster.rpush(key, strList.toArray(new String[0]));
		jedisCluster.expire(key, (int) timeout);
		return true;
	}

	@Override
	public long lsize(String key) {
		return jedisCluster.llen(key);
	}

	@Override
	public T lindex(String key, long index) {
		return serializer.deserialize(jedisCluster.lindex(key, index));
	}

	@Override
	public List lrange(String key, long start, long end) {
		List strList = jedisCluster.lrange(key, start, end);
		List tList = new ArrayList<>();
		if (strList == null || strList.size() <= 0) {
			return tList;
		}
		for (String str: strList) {
			tList.add(serializer.deserialize(str));
		}
		return tList;
	}

	@Override
	public void ltrim(String key, long start, long end) {
		jedisCluster.ltrim(key, start, end);
	}

	@Override
	public void lset(String key, long index, T value) {
		jedisCluster.lset(key, index, serializer.serialize(value));
	}

	@Override
	public T lpop(String key) {
		return serializer.deserialize(jedisCluster.lpop(key));
	}

	@Override
	public T rpop(String key) {
		return serializer.deserialize(jedisCluster.rpop(key));
	}

	@Override
	public void sadd(String key, T t, long timeout) {
		jedisCluster.sadd(key, serializer.serialize(t));
		jedisCluster.expire(key, (int) timeout);
	}

	@Override
	public void sadd(String key, List valList, long timeout) {
		if (valList == null || valList.size() <= 0) {
			return;
		}
		List strList = new ArrayList<>();
		for (T t: valList) {
			strList.add(serializer.serialize(t));
		}
		jedisCluster.sadd(key, strList.toArray(new String[0]));
		jedisCluster.expire(key, (int) timeout);
	}

	@Override
	public long slen(String key) {
		return jedisCluster.scard(key);
	}

	@Override
	public Set sdiff(String key, Collection otherKeys) {
		List keyList = new ArrayList<>();
		keyList.add(key);
		keyList.addAll(otherKeys);
		Set strSet = jedisCluster.sdiff(keyList.toArray(new String[0]));
		Set tSet = new HashSet<>();
		if (strSet == null || strSet.isEmpty()) {
			return tSet;
		}
		for (String str: strSet) {
			tSet.add(serializer.deserialize(str));
		}
		return tSet;
	}

	@Override
	public void sdiffStore(String key, Collection otherKeys, String destKey) {
		List keyList = new ArrayList<>();
		keyList.add(key);
		keyList.addAll(otherKeys);
		jedisCluster.sdiffstore(destKey, keyList.toArray(new String[0]));
	}

	@Override
	public Set sinter(String key, Collection otherKeys) {
		List keyList = new ArrayList<>();
		keyList.add(key);
		keyList.addAll(otherKeys);
		Set strSet = jedisCluster.sinter(keyList.toArray(new String[0]));
		Set tSet = new HashSet<>();
		if (strSet == null || strSet.isEmpty()) {
			return tSet;
		}
		for (String str: strSet) {
			tSet.add(serializer.deserialize(str));
		}
		return tSet;
	}

	@Override
	public void sinterStore(String key, Collection otherKeys, String destKey) {
		int len = otherKeys.size();
		String[] arr = new String[len + 1];
		arr[0] = key;
		int i = 1;
		for (String otherKey: otherKeys) {
			arr[i++] = otherKey;
		}
		jedisCluster.sinterstore(destKey, arr);
	}

	@Override
	public Set sunion(String key, Collection otherKeys) {
		List keyList = new ArrayList<>();
		keyList.add(key);
		keyList.addAll(otherKeys);
		Set strSet = jedisCluster.sunion(keyList.toArray(new String[0]));
		Set tSet = new HashSet<>();
		if (strSet == null || strSet.isEmpty()) {
			return tSet;
		}
		for (String str: strSet) {
			tSet.add(serializer.deserialize(str));
		}
		return tSet;
	}

	@Override
	public void sunionStore(String key, Collection otherKeys, String destKey) {
		int len = otherKeys.size();
		String[] arr = new String[len + 1];
		arr[0] = key;
		int i = 1;
		for (String otherKey: otherKeys) {
			arr[i++] = otherKey;
		}
		jedisCluster.sunionstore(destKey, arr);
	}

	@Override
	public boolean sisMember(String key, T member) {
		return jedisCluster.sismember(key, serializer.serialize(member));
	}

	@Override
	public Set smembers(String key) {
		Set strSet = jedisCluster.smembers(key);
		Set tSet = new HashSet<>();
		if (strSet == null || strSet.isEmpty()) {
			return tSet;
		}
		for (String str: strSet) {
			tSet.add(serializer.deserialize(str));
		}
		return tSet;
	}

	@Override
	public boolean smove(String sourceKey, String destKey, T member) {
		return jedisCluster.smove(sourceKey, destKey, serializer.serialize(member)) > 0;
	}

	@Override
	public boolean sremove(String key, Collection members) {
		if (members == null || members.size() <= 0) {
			return false;
		}
		List strList = new ArrayList<>();
		for (T t: members) {
			strList.add(serializer.serialize(t));
		}
		return jedisCluster.srem(key, strList.toArray(new String[0])) > 0;
	}

	@Override
	public void zadd(String key, T value, double score, long timeout) {
		jedisCluster.zadd(key, score, serializer.serialize(value));
		jedisCluster.expire(key, (int) timeout);
	}

	@Override
	public void zadd(String key, Map memScore, long timeout) {
		if (memScore == null || memScore.isEmpty()) {
			return;
		}
		Map strMap = new HashMap<>();
		for (Map.Entry entry: memScore.entrySet()) {
			strMap.put(serializer.serialize(entry.getKey()), entry.getValue());
		}
		jedisCluster.zadd(key, strMap);
		jedisCluster.expire(key, (int) timeout);
	}

	@Override
	public long zlen(String key) {
		return jedisCluster.zcard(key);
	}

	@Override
	public long zcount(String key, double min, double max) {
		return jedisCluster.zcount(key, min, max);
	}

	@Override
	public void zincrby(String key, T member, double increment) {
		jedisCluster.zincrby(key, increment, serializer.serialize(member));
	}

	@Override
	public void zinterStore(String key, Collection otherKeys, String destKey) {
		int len = otherKeys.size();
		String[] arr = new String[len + 1];
		arr[0] = key;
		int i = 1;
		for (String otherKey: otherKeys) {
			arr[i++] = otherKey;
		}
		jedisCluster.zinterstore(destKey, arr);
	}

	@Override
	public void zunionStore(String key, Collection otherKeys, String destKey) {
		int len = otherKeys.size();
		String[] arr = new String[len + 1];
		arr[0] = key;
		int i = 1;
		for (String otherKey: otherKeys) {
			arr[i++] = otherKey;
		}
		jedisCluster.zunionstore(destKey, arr);
	}

	@Override
	public boolean zremove(String key, Collection members) {
		if (members == null || members.size() <= 0) {
			return false;
		}
		List strList = new ArrayList<>();
		for (T t: members) {
			strList.add(serializer.serialize(t));
		}
		return jedisCluster.zrem(key, strList.toArray(new String[0])) > 0;
	}

	@Override
	public Double zscore(String key, T member) {
		return jedisCluster.zscore(key, serializer.serialize(member));
	}

	@Override
	public Long zrank(String key, T member) {
		return jedisCluster.zrank(key, serializer.serialize(member));
	}

	@Override
	public boolean lock(String key, T owner, long timeout) {
		return lock(key, owner, timeout, false);
	}

	@Override
	public boolean lock(String key, T owner, long timeout, boolean reentrant) {
		if (owner == null) {
			return false;
		}
		DefaultRedisScript redisScript = new DefaultRedisScript<>();
		redisScript.setResultType(String.class);
		redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/getLock.lua")));
		Object result = jedisCluster.eval(redisScript.getScriptAsString(), Collections.singletonList(key)
				, Arrays.asList(String.valueOf(reentrant), serializer.serialize(owner), String.valueOf(timeout)));
		return result != null && "OK".equalsIgnoreCase(result.toString());
	}

	@Override
	public  T tlock(String key, T owner, long timeout) {
		if (owner == null) {
			return null;
		}
		DefaultRedisScript redisScript = new DefaultRedisScript<>();
		redisScript.setResultType(String.class);
		redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/getLockt.lua")));
		Object result = jedisCluster.eval(redisScript.getScriptAsString(), Collections.singletonList(key)
				, Arrays.asList(serializer.serialize(owner), String.valueOf(timeout)));
		return result == null ? null : serializer.deserialize(result.toString());
	}

	@Override
	public boolean unlock(String key, T owner) {
		if (owner == null) {
			return false;
		}
		if (!contains(key)) {
			return true;
		}
		DefaultRedisScript redisScript = new DefaultRedisScript<>();
		redisScript.setResultType(Long.class);
		redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/releaseLock.lua")));
		Object result = jedisCluster.eval(redisScript.getScriptAsString(), Collections.singletonList(key), Collections.singletonList(serializer.serialize(owner)));
		return result != null && "1".equals(result.toString());
	}

	@Override
	public String execute(String script, List keyList, List argList) {
		return execute(script, keyList, argList, String.class);
	}

	@Override
	public S execute(String script, List keyList, List argList, Class returnType) {
		List strArgList = new ArrayList<>();
		if (argList != null && argList.size() > 0) {
			for (T t: argList) {
				strArgList.add(serializer.serialize(t));
			}
		}
		DefaultRedisScript redisScript = new DefaultRedisScript<>();
		redisScript.setResultType(returnType);
		redisScript.setScriptText(script);
		return (S) jedisCluster.eval(redisScript.getScriptAsString(), keyList, strArgList);
	}
}