package com.boot.security.server.utils.redis;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.*;

import java.util.*;
import java.util.Map.Entry;

public class JedisHelper {
	//private static Cache jobCache = CacheManager.getInstance().getCache("redis_job_list");

	private static int sleepTime = 300; // 默认sleep时间 300毫秒
	private static int sleepMaxCount = 3; // 默认等待次数

	public static String zMinScore = "-inf"; // 有序集(Sorted set) 的score的最小值
	public static String zMaxScore = "+inf"; // 有序集(Sorted set) 的score的最大值

	private static JedisManager jm = JedisManager.getInstance();

//	public static void addjob(String k) {
//		Element e = new Element(k, k);
//		jobCache.put(e);
//	}
//
//	public static void removeJob(String k) {
//		jobCache.remove(k);
//	}
//
//	public static boolean checkkey(String k) {
//		Element e = jobCache.get(k);
//		if (null != e) {
//			return true;
//		} else {
//			return false;
//		}
//	}
	public static Long hincrBy(String key, String field, long increment) {
		ShardedJedis jedis = null;
		Long value = null;

		try {
			jedis = jm.getShardedJedis();
			value = jedis.hincrBy(key, field, increment);
			jm.returnSharedJedis(jedis);
		} catch (Exception var8) {
			//this.logger.error("JedisHelper.", var8);
			jm.returnBrokenSharedJedis(jedis);
		}

		return value;
	}

	public static void set(String key, Object o) {
		String json = JSON.toJSONString(o);

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.set(key, json);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void set(String key, int expires, Object o) {
		String json = JSON.toJSONString(o);

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Transaction t = jedis.getShard(key).multi();
			t.set(key, json);
			t.expire(key, expires);
			t.exec();

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}
	}
	public static int setnx(String key, Object o) {
		ShardedJedis jedis = null;
		String value = JSON.toJSONString(o);
		Long result = 0L;
		try {
			jedis = jm.getShardedJedis();
			result = jedis.setnx(key, value);
			jm.returnSharedJedis(jedis);
			return result.intValue();
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
			return 0;
		}
	}
	public static int setnx(String key, int expires, Object o) {
		ShardedJedis jedis = null;
		String value = JSON.toJSONString(o);
		Long result = 0L;
		try {
			jedis = jm.getShardedJedis();
			Transaction t = jedis.getShard(key).multi();
			Response<Long> response = t.setnx(key, value);
			t.expire(key, expires);
			t.exec();
			if (response != null) {
				result = response.get();
			}
			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
			return 0;
		}
		if (result == null) {
			return 0;
		}
		return result.intValue();
	}

	public static <T> T getSet(Class<T> clazz, String key, Object o) {
		ShardedJedis jedis = null;
		try {
			String value = null;
			if (!(o instanceof String)) {
				value = JSON.toJSONString(o);
			} else {
				value = (String) o;
			}
			jedis = jm.getShardedJedis();
			String json = jedis.getSet(key, value);
			jm.returnSharedJedis(jedis);

			if (StringUtils.isNotEmpty(json)) {
				T t = JSON.parseObject(json, clazz);
				return t;
			} else {
				return null;
			}
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
			return null;
		}
	}

//	public static void loadDataToRedis(final String lockKey, final RedisLoader loader) {
//		ThreadPoolManager.es.execute(new Runnable() {
//			@Override
//			public void run() {
//				doJobWithRedisDistributedLock(lockKey, loader);
//			}
//		});
//	}

	public static void doJobWithRedisDistributedLock(final String lockKey, final RedisLoader loader) {
		try {
			int lock = 0;
			int timeout = 10000;

			long timeStamp = getCurrentTime() + timeout + 1;
			lock = setnx(lockKey, timeout, timeStamp);
			if (lock == 1) {
				loader.doJob();
				if (getCurrentTime() < get(Long.class, lockKey)) {
					del(lockKey);
				}
				return;
			} else {
				Long expireTime = get(Long.class, lockKey);
				expireTime = expireTime == null ? 0 : expireTime;
				if (getCurrentTime() > expireTime) {
					Long valueBeforeSet = getSet(Long.class, lockKey, timeStamp);
					valueBeforeSet = valueBeforeSet == null ? 0 : valueBeforeSet;
					if (getCurrentTime() > valueBeforeSet) {
						loader.doJob();
						if (getCurrentTime() < get(Long.class, lockKey)) {
							del(lockKey);
						}
						return;
					}
				}
			}
		} catch (Exception e) {
			//ignore
		}
	}

	private static long getCurrentTime() {
		return System.currentTimeMillis();
	}

	public static boolean exists(String key) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			boolean result = jedis.exists(key);
			jm.returnSharedJedis(jedis);
			return result;
		} catch (Exception e) {
			// 
			System.out.println(e.getStackTrace());
			jm.returnBrokenSharedJedis(jedis);
			return false;
		}
	}
	/**
	 * 为给定 key 设置生存时间，当 key 过期时(生存时间为 0 )，它会被自动删除。
	 * @param key KEY值
	 * @param seconds 过期时间，单位：秒
	 */
	public static void expire(String key, int seconds) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.expire(key, seconds);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}
	}
	/**
	 * 为给定 key 获取生存时间
	 * @param key KEY值
	 */
	public static long ttl(String key) {
		Long ret = 0l;
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			ret = jedis.ttl(key);

			jm.returnSharedJedis(jedis);

		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}
		return ret;
	}
	public static <T> T get(Class<T> clazz, String key) {
		String json = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			json = jedis.get(key);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}

		T t = JSON.parseObject(json, clazz);
		return t;
	}

	public static <T> List<T> getList(Class<T> clazz, String key) {
		String json = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			json = jedis.get(key);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}

		List<T> list = JSON.parseArray(json, clazz);
		return list;
	}



	public static Long incr(String key) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Long l = jedis.incr(key);

			jm.returnSharedJedis(jedis);
			return l;
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
			return 0L;
		}
	}

	public static Long incrby(String key, int increment) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Long l = jedis.incrBy(key, increment);
			jm.returnSharedJedis(jedis);
			return l;
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
			return 0L;
		}
	}
	public static Long incrby(String key, int increment, int expireSecond) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Long l = jedis.incrBy(key, increment);
			jedis.expire(key, expireSecond);
			jm.returnSharedJedis(jedis);
			return l;
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
			return 0L;
		}
	}

	public static Long decr(String key) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Long l = jedis.decr(key);

			jm.returnSharedJedis(jedis);
			return l;
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
			return 0L;
		}
	}

	public static Long decrby(String key, int increment) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Long l = jedis.decrBy(key, increment);

			jm.returnSharedJedis(jedis);
			return l;
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
			return 0L;
		}
	}

	public static void del(String key) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.del(key);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void hdel(String key, String... fields) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.hdel(key, fields);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void hset(String key, String field, Object o) {
		String json = JSON.toJSONString(o);

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.hset(key, field, json);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void hset(String key, String field, int expire, Object o) {
		String json = JSON.toJSONString(o);

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Transaction t = jedis.getShard(key).multi();
			t.hset(key, field, json);
			t.expire(key, expire);
			t.exec();

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			// 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static <T> T hget(Class<T> clazz, String key, String field) {
		String json = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			json = jedis.hget(key, field);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}

		T t = JSON.parseObject(json, clazz);
		return t;
	}

	public static <T> Map<String, T> hgetAll(Class<T> valueClazz, String key) {
		Map<String, String> json = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			json = jedis.hgetAll(key);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}

		Map<String, T> map = new HashMap<String, T>();
		for (Entry<String, String> item : json.entrySet()) {
			T t = JSON.parseObject(item.getValue(), valueClazz);
			map.put(item.getKey(), t);
		}
		return map;
	}
	

	public static void lpush(String key, int expires, Object... os) {
		String[] jsons = new String[os.length];
		for (int i = 0; i < jsons.length; i++) {
			jsons[i] = JSON.toJSONString(os[i]);
		}

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Transaction t = jedis.getShard(key).multi();
			for (String json : jsons) {
				t.lpush(key, json);
			}
			t.expire(key, expires);
			t.exec();

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void rpush(String key, Object... os) {
		String[] jsons = new String[os.length];
		for (int i = 0; i < jsons.length; i++) {
			jsons[i] = JSON.toJSONString(os[i]);
			ShardedJedis jedis = null;
			try {
				jedis = jm.getShardedJedis();
				jedis.rpush(key, jsons[i]);

				jm.returnSharedJedis(jedis);
			} catch (Exception e) {
				 
				jm.returnBrokenSharedJedis(jedis);
			}
		}

	}

	public static void rpush(String key, List<? extends Object> list) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			for (Object obj : list) {
				jedis.rpush(key, obj.toString());
			}

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void lrem(String key, long count, Object value) {
		ShardedJedis jedis = null;

		try {
			jedis = jm.getShardedJedis();
			String v = JSON.toJSONString(value);
			jedis.lrem(key, count, v);
			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);

		}
	}

	public static long llen(String key) {
		ShardedJedis jedis = null;

		try {
			jedis = jm.getShardedJedis();
			long length = jedis.llen(key);
			jm.returnSharedJedis(jedis);
			return length;
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
			return 0L;
		}
	}

	public static void ltrim(String key, long start, long end) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.ltrim(key, start, end);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static <T> List<T> lrange(Class<T> clazz, String key, long start, long end) {
		List<T> list = new ArrayList<T>();
		List<String> sList = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			sList = jedis.lrange(key, start, end);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}

		if (sList.isEmpty()) {
			for (String str : sList) {
				T t = JSON.parseObject(str, clazz);
				list.add(t);
			}
		}
		return list;
	}

	public static void lset(String key, long index, Object value) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.lset(key, index, JSON.toJSONString(value));

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static <T> T lindex(Class<T> clazz, String key, int index) {
		ShardedJedis jedis = null;
		String str = null;
		try {
			jedis = jm.getShardedJedis();
			str = jedis.lindex(key, index);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}

		return JSON.parseObject(str, clazz);
	}

	public static int zcount(String key) {
		int count = 0;
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			count = jedis.zcount(key, zMinScore, zMaxScore).intValue();
			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);

		}
		return count;
	}

	public static void zadd(String key, Map<? extends Object, Double> scoreObjects) {
		//		List<Map<Double, String>> list = new ArrayList<Map<Double, String>>();
		//		for (Entry<? extends Object, Double> enrty : scoreObjects.entrySet()) {
		//			String json = JSON.toJSONString(enrty.getKey());
		//			Double score = enrty.getValue();
		//
		//			boolean isAdd = false;
		//			int size = list.size();
		//			int index = 0;
		//			while (index < size) {
		//				Map<Double, String> scoreMembers = list.get(index);
		//				if (scoreMembers.containsKey(score)) {
		//					index++;
		//				} else {
		//					scoreMembers.put(score, json);
		//					isAdd = true;
		//					break;
		//				}
		//			}
		//			if (!isAdd) {
		//				Map<Double, String> scoreMembers = new HashMap<Double, String>();
		//				scoreMembers.put(score, json);
		//				list.add(scoreMembers);
		//			}
		//		}
		//
		//		ShardedJedis jedis = null;
		//		try {
		//			for (Map<Double, String> scoreMembers : list) {
		//				jedis = jm.getShardedJedis();
		//				jedis.zadd(key, scoreMembers);
		//			}
		//
		//			jm.returnSharedJedis(jedis);
		//		} catch (Exception e) {
		//			 
		//			jm.returnBrokenSharedJedis(jedis);
		//		}

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Transaction t = jedis.getShard(key).multi();
			for (Entry<? extends Object, Double> enrty : scoreObjects.entrySet()) {
				String json = JSON.toJSONString(enrty.getKey());
				Double score = enrty.getValue();
				t.zadd(key, score, json);
			}
			t.exec();

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void zadd(String key, int expire, Map<? extends Object, Double> scoreObjects) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Transaction t = jedis.getShard(key).multi();
			for (Entry<? extends Object, Double> enrty : scoreObjects.entrySet()) {
				String json = JSON.toJSONString(enrty.getKey());
				Double score = enrty.getValue();
				t.zadd(key, score, json);
			}
			t.expire(key, expire);
			t.exec();

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void zadd(String key, int expire, double score, Object o) {
		String json = JSON.toJSONString(o);

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.zadd(key, score, json);

			Transaction t = jedis.getShard(key).multi();
			t.zadd(key, score, json);
			t.expire(key, expire);
			t.exec();

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void zadd(String key, double score, Object o) {
		String json = JSON.toJSONString(o);

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.zadd(key, score, json);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static long zcard(String key) {
		long count = 0;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			count = jedis.zcard(key);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
		return count;
	}

	public static long zcount(String key, String min, String max) {
		long count = 0;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			count = jedis.zcount(key, min, max);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
		return count;
	}

	public static void zrem(String key, Object o) {
		String json = JSON.toJSONString(o);
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.zrem(key, json);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static void zremrangebyrank(String key, int start, int end) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.zremrangeByRank(key, start, end);
			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	/**
	 * 用于判断member是否在zset列表中
	 * @param key zset缓存key值
	 * @param member zset列表中某条记录的索引
	 * @return true存在；false不存在
	 * @author lf
	 */
	public static boolean isMemberExists(String key, String member) {
		Double value = zscore(key, member);
		if (value == null) {
			return false;
		}
		return value > 0;
	}

	public static Double zscore(String key, String member) {
		ShardedJedis jedis = null;
		Double score = null;
		try {
			jedis = jm.getShardedJedis();
			score = jedis.zscore(key, member);
			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
		return score;
	}

	public static void zincrby(String key, double score, Object o) {
		String json = JSON.toJSONString(o);

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.zincrby(key, score, json);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	public static <T> Map<T, Double> zrevrange(Class<T> clazz, String key, long start, long end) {
		Map<T, Double> map = new LinkedHashMap<T, Double>();
		Set<Tuple> set = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			set = jedis.zrevrangeWithScores(key, start, end);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
			return null;
		}

		for (Tuple tuple : set) {
			T t = JSON.parseObject(tuple.getElement(), clazz);
			Double score = tuple.getScore();
			map.put(t, score);
		}
		return map;
	}

	public static <T> Map<T, Double> zrange(Class<T> clazz, String key, long start, long end) {
		Map<T, Double> map = new LinkedHashMap<T, Double>();
		Set<Tuple> set = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			set = jedis.zrangeWithScores(key, start, end);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
			return null;
		}

		for (Tuple tuple : set) {
			T t = JSON.parseObject(tuple.getElement(), clazz);
			Double score = tuple.getScore();
			map.put(t, score);
		}
		return map;
	}

	private static <T> Map<T, Double> zrevrangeByScoreCommon(Class<T> clazz, String key, Object maxScore,
			Object minScore, int offset, int count) {
		Map<T, Double> map = new LinkedHashMap<T, Double>();
		Set<Tuple> set = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			if (maxScore.getClass().equals(Long.class) && minScore.getClass().equals(Long.class)) {
				set = jedis.zrevrangeByScoreWithScores(key, Long.valueOf(maxScore.toString()), Long.valueOf(minScore
						.toString()), offset, count);
			} else if (maxScore.getClass().equals(Double.class) && minScore.getClass().equals(Double.class)) {
				set = jedis.zrevrangeByScoreWithScores(key, Double.valueOf(maxScore.toString()), Double
						.valueOf(minScore.toString()), offset, count);
			} else if (maxScore.getClass().equals(String.class) && minScore.getClass().equals(String.class)) {
				set = jedis.zrevrangeByScoreWithScores(key, maxScore.toString(), minScore.toString(), offset, count);
			}

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
			return null;
		}

		for (Tuple tuple : set) {
			T t = JSON.parseObject(tuple.getElement(), clazz);
			Double score = tuple.getScore();
			map.put(t, score);
		}
		return map;
	}

	public static <T> Map<T, Double> zrevrangeByScore(Class<T> clazz, String key, String max, String min, int offset,
			int count) {
		return zrevrangeByScoreCommon(clazz, key, max, min, offset, count);
	}

	public static <T> Map<T, Double> zrevrangeByScore(Class<T> clazz, String key, double max, double min, int offset,
			int count) {
		return zrevrangeByScoreCommon(clazz, key, max, min, offset, count);
	}

	public static <T> Map<T, Double> zrevrangeByScore(Class<T> clazz, String key, long max, long min, int offset,
			int count) {
		return zrevrangeByScoreCommon(clazz, key, max, min, offset, count);
	}

	private static <T> Map<T, Double> zrevrangeByScoreCommon(Class<T> clazz, String key, Object maxScore,
			Object minScore) {
		Map<T, Double> map = new LinkedHashMap<T, Double>();
		Set<Tuple> set = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			if (maxScore.getClass().equals(Long.class) && minScore.getClass().equals(Long.class)) {
				set = jedis.zrevrangeByScoreWithScores(key, Long.valueOf(maxScore.toString()), Long.valueOf(minScore
						.toString()));
			} else if (maxScore.getClass().equals(Double.class) && minScore.getClass().equals(Double.class)) {
				set = jedis.zrevrangeByScoreWithScores(key, Double.valueOf(maxScore.toString()), Double
						.valueOf(minScore.toString()));
			} else if (maxScore.getClass().equals(String.class) && minScore.getClass().equals(String.class)) {
				set = jedis.zrevrangeByScoreWithScores(key, maxScore.toString(), minScore.toString());
			}

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
			return null;
		}

		for (Tuple tuple : set) {
			T t = JSON.parseObject(tuple.getElement(), clazz);
			Double score = tuple.getScore();
			map.put(t, score);
		}
		return map;
	}

	public static <T> Map<T, Double> zrevrangeByScore(Class<T> clazz, String key, String max, String min) {
		return zrevrangeByScoreCommon(clazz, key, max, min);
	}

	public static <T> Map<T, Double> zrevrangeByScore(Class<T> clazz, String key, double max, double min) {
		return zrevrangeByScoreCommon(clazz, key, max, min);
	}

	public static <T> Map<T, Double> zrevrangeByScore(Class<T> clazz, String key, long max, long min) {
		return zrevrangeByScoreCommon(clazz, key, max, min);
	}

	/**
	 * 移除有序集 key 中，指定排名(rank)区间内的所有成员<br>
	 * 区间分别以下标参数 start 和 end 指出，包含 start 和 end 在内
	 * @param key key值
	 * @param start 起始下标
	 * @param end 结束下标
	 */
	public static void zremrangeByScore(String key, double start, double end) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			jedis.zremrangeByScore(key, start, end);
			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	private static <T> Map<T, Double> zrangeByScoreCommon(Class<T> clazz, String key, Object maxScore, Object minScore,
			int offset, int count) {

		Map<T, Double> map = new LinkedHashMap<T, Double>();
		Set<Tuple> set = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			if (maxScore.getClass().equals(Long.class) && minScore.getClass().equals(Long.class)) {
				set = jedis.zrangeByScoreWithScores(key, Long.valueOf(minScore.toString()), Long.valueOf(maxScore
						.toString()), offset, count);
			} else if (maxScore.getClass().equals(Double.class) && minScore.getClass().equals(Double.class)) {
				set = jedis.zrangeByScoreWithScores(key, Double.valueOf(minScore.toString()), Double.valueOf(maxScore
						.toString()), offset, count);
			} else if (maxScore.getClass().equals(String.class) && minScore.getClass().equals(String.class)) {
				set = jedis.zrangeByScoreWithScores(key, minScore.toString(), maxScore.toString(), offset, count);
			}

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
			return null;
		}

		for (Tuple tuple : set) {
			T t = JSON.parseObject(tuple.getElement(), clazz);
			Double score = tuple.getScore();
			map.put(t, score);
		}
		return map;
	}

	public static <T> Map<T, Double> zrangeByScore(Class<T> clazz, String key, String max, String min, int offset,
			int count) {
		return zrangeByScoreCommon(clazz, key, max, min, offset, count);
	}

	public static <T> Map<T, Double> zrangeByScore(Class<T> clazz, String key, double max, double min, int offset,
			int count) {
		return zrangeByScoreCommon(clazz, key, max, min, offset, count);
	}

	public static <T> Map<T, Double> zrangeByScore(Class<T> clazz, String key, long max, long min, int offset, int count) {
		return zrangeByScoreCommon(clazz, key, max, min, offset, count);
	}

	public static Set<String> keys(String key) {
		System.out.println("keys() start:" + new Date());
		Set<String> result = new HashSet<String>();
		if (StringUtils.isBlank(key)) {
			return result;
		}
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Iterator<Jedis> it = jedis.getAllShards().iterator();
			while (it.hasNext()) {
				Jedis j = it.next();
				Set<String> r = j.keys(key);
				if (r != null) {
					result.addAll(r);
				}
			}
			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			e.printStackTrace();
			jm.returnBrokenSharedJedis(jedis);
		}
		System.out.println("keys end:" + new Date());
		return result;
	}

	/** 页面缓存存取专用*/
	public static void setPage(String key, int expires, String o) {
		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			Transaction t = jedis.getShard(key).multi();
			t.set(key, o);
			t.expire(key, expires);
			t.exec();

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
	}

	/** 页面缓存存取专用*/
	public static String getPage(String key) {
		String o = null;

		ShardedJedis jedis = null;
		try {
			jedis = jm.getShardedJedis();
			o = jedis.get(key);

			jm.returnSharedJedis(jedis);
		} catch (Exception e) {
			 
			jm.returnBrokenSharedJedis(jedis);
		}
		return o;
	}


}
