/**
* Copyright 2014 Duan Bingnan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.pinus4j.cache.impl;
import java.util.List;
import java.util.Map;
import org.pinus4j.cache.IPrimaryCache;
import org.pinus4j.cluster.resources.ShardingDBResource;
import org.pinus4j.entity.meta.EntityPK;
import org.pinus4j.utils.IOUtil;
import org.pinus4j.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.ShardedJedis;
import com.google.common.collect.Maps;
public class RedisPrimaryCacheImpl extends AbstractRedisCache implements IPrimaryCache {
public static final Logger LOG = LoggerFactory.getLogger(RedisPrimaryCacheImpl.class);
public RedisPrimaryCacheImpl(String address, int expire) {
super(address, expire);
}
@Override
public void setCountGlobal(String clusterName, String tableName, long count) {
String key = buildGlobalCountKey(clusterName, tableName);
_setCount(key, count);
}
@Override
public long decrCountGlobal(String clusterName, String tableName, int delta) {
String key = buildGlobalCountKey(clusterName, tableName);
return _decrCount(key, delta);
}
@Override
public long incrCountGlobal(String clusterName, String tableName, int delta) {
String key = buildGlobalCountKey(clusterName, tableName);
return _incrCount(key, delta);
}
@Override
public long getCountGlobal(String clusterName, String tableName) {
String key = buildGlobalCountKey(clusterName, tableName);
return _getCount(key);
}
@Override
public void putGlobal(String clusterName, String tableName, Map<EntityPK, ? extends Object> data) {
if (data == null || data.isEmpty()) {
return;
}
String key = buildGlobalKey(clusterName, tableName, null);
_put(key, data);
}
@Override
public <T> Map<EntityPK, T> getGlobal(String clusterName, String tableName, EntityPK[] pks) {
String key = buildGlobalKey(clusterName, tableName, null);
return _get(key, pks);
}
@Override
public void removeGlobal(String clusterName, String tableName, List<EntityPK> pks) {
String key = buildGlobalKey(clusterName, tableName, null);
_remove(key, pks);
}
@Override
public void setCount(ShardingDBResource db, long count) {
String key = buildCountKey(db);
_setCount(key, count);
}
@Override
public long decrCount(ShardingDBResource db, long delta) {
String key = buildCountKey(db);
return _decrCount(key, delta);
}
@Override
public long incrCount(ShardingDBResource db, long delta) {
String key = buildCountKey(db);
return _incrCount(key, delta);
}
@Override
public long getCount(ShardingDBResource db) {
String key = buildCountKey(db);
return _getCount(key);
}
@Override
public void put(ShardingDBResource db, Map<EntityPK, ? extends Object> data) {
if (data == null || data.isEmpty()) {
return;
}
String key = buildKey(db, null);
_put(key, data);
}
@Override
public <T> Map<EntityPK, T> get(ShardingDBResource dbResource, EntityPK[] pks) {
String key = buildKey(dbResource, null);
return _get(key, pks);
}
@Override
public void remove(ShardingDBResource db, List<EntityPK> pks) {
String key = buildKey(db, null);
_remove(key, pks);
}
private void _setCount(String key, long count) {
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
_removeCount(key);
redisClient.incrBy(key, count);
if (LOG.isDebugEnabled()) {
LOG.debug("[PRIMARY CACHE] - " + key + " set count=" + count);
}
} catch (Exception e) {
LOG.warn("操作缓存失败:" + e.getMessage());
} finally {
if (redisClient != null)
redisClient.close();
}
}
private void _removeCount(String key) {
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
redisClient.del(key);
if (LOG.isDebugEnabled()) {
LOG.debug("[PRIMARY CACHE] - delete " + key);
}
} catch (Exception e) {
LOG.warn("操作缓存失败:" + e.getMessage());
} finally {
if (redisClient != null)
redisClient.close();
}
}
private long _decrCount(String key, long delta) {
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
if (redisClient.get(key) != null) {
long count = redisClient.decrBy(key, delta);
if (LOG.isDebugEnabled()) {
LOG.debug("[PRIMARY CACHE] - decr " + key + " " + delta);
}
return count;
}
} catch (Exception e) {
LOG.warn("操作缓存失败:" + e.getMessage());
} finally {
if (redisClient != null)
redisClient.close();
}
return -1;
}
private long _incrCount(String key, long delta) {
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
if (redisClient.get(key) != null) {
long count = redisClient.incrBy(key, delta);
if (LOG.isDebugEnabled()) {
LOG.debug("[PRIMARY CACHE] - incr " + key + " " + delta);
}
return count;
}
} catch (Exception e) {
LOG.warn("操作缓存失败:" + e.getMessage());
} finally {
if (redisClient != null)
redisClient.close();
}
return -1;
}
private long _getCount(String key) {
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
String count = (String) redisClient.get(key);
if (StringUtil.isNotBlank(count)) {
if (LOG.isDebugEnabled()) {
LOG.debug("[PRIMARY CACHE] - get " + key + " " + count);
}
return Long.parseLong(count);
}
} catch (Exception e) {
LOG.warn("操作缓存失败:" + e.getMessage());
} finally {
if (redisClient != null)
redisClient.close();
}
return -1l;
}
private <T> void _put(String key, Map<EntityPK, T> param) {
if (param == null || param.isEmpty()) {
return;
}
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
Map<byte[], byte[]> data = Maps.newLinkedHashMap();
for (Map.Entry<EntityPK, T> entry : param.entrySet()) {
data.put(IOUtil.getBytes(entry.getKey()), IOUtil.getBytes(entry.getValue()));
}
redisClient.hmset(key.getBytes(), data);
redisClient.expire(key.getBytes(), expire);
if (LOG.isDebugEnabled()) {
LOG.debug("[PRIMARY CACHE] - put (" + data.size() + ") to cache " + key);
}
} catch (Exception e) {
LOG.warn("操作缓存失败:" + e.getMessage());
} finally {
if (redisClient != null)
redisClient.close();
}
}
private <T> Map<EntityPK, T> _get(String key, EntityPK[] pks) {
Map<EntityPK, T> datas = Maps.newLinkedHashMap();
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
byte[][] fields = new byte[pks.length][];
for (int i = 0; i < pks.length; i++) {
fields[i] = IOUtil.getBytes(pks[i]);
}
List<byte[]> result = redisClient.hmget(key.getBytes(), fields);
if (LOG.isDebugEnabled()) {
LOG.debug("[PRIMARY CACHE] - get " + key + " hits = " + result.size());
}
T value = null;
for (int i = 0; i < pks.length; i++) {
value = (T) IOUtil.getObject(result.get(i), Object.class);
if (value != null)
datas.put(pks[i], value);
}
} catch (Exception e) {
LOG.warn("操作缓存失败:" + e.getMessage());
} finally {
if (redisClient != null)
redisClient.close();
}
return datas;
}
private void _remove(String key, List<EntityPK> pks) {
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
byte[][] fields = new byte[pks.size()][];
for (int i = 0; i < pks.size(); i++) {
fields[i] = IOUtil.getBytes(pks.get(i));
}
redisClient.hdel(key.getBytes(), fields);
if (LOG.isDebugEnabled()) {
LOG.debug("[PRIMARY CACHE] - remove " + key + " " + pks);
}
} catch (Exception e) {
LOG.warn("操作缓存失败:" + e.getMessage());
} finally {
if (redisClient != null)
redisClient.close();
}
}
}