/**
* 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.Collection;
import java.util.List;
import java.util.Set;
import org.pinus4j.cache.ISecondCache;
import org.pinus4j.cluster.resources.ShardingDBResource;
import org.pinus4j.utils.IOUtil;
import org.pinus4j.utils.SecurityUtil;
import org.pinus4j.utils.StringUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ShardedJedis;
public class RedisSecondCacheImpl extends AbstractRedisCache implements ISecondCache {
public RedisSecondCacheImpl(String address, int expire) {
super(address, expire);
}
@Override
public void putGlobal(String whereKey, String clusterName, String tableName, List data) {
if (StringUtil.isBlank(whereKey) || data == null || data.isEmpty()) {
return;
}
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
String cacheKey = _buildGlobalCacheKey(whereKey, clusterName, tableName);
redisClient.set(cacheKey.getBytes(), IOUtil.getBytes(data));
redisClient.expire(cacheKey.getBytes(), expire);
if (LOG.isDebugEnabled()) {
LOG.debug("[SECOND CACHE] - put to cache done, key: " + cacheKey);
}
} catch (Exception e) {
LOG.warn("operate second cache failure");
} finally {
if (redisClient != null)
redisClient.close();
}
}
@Override
public List getGlobal(String whereKey, String clusterName, String tableName) {
if (StringUtil.isBlank(whereKey)) {
return null;
}
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
String cacheKey = _buildGlobalCacheKey(whereKey, clusterName, tableName);
List data = IOUtil.getObject(redisClient.get(cacheKey.getBytes()), List.class);
if (LOG.isDebugEnabled() && data != null) {
LOG.debug("[SECOND CACHE] - key " + cacheKey + " hit");
}
return data;
} catch (Exception e) {
e.printStackTrace();
LOG.warn("operate second cache failure");
} finally {
if (redisClient != null)
redisClient.close();
}
return null;
}
@Override
public void removeGlobal(String clusterName, String tableName) {
ShardedJedis redisClient = null;
String cacheKey = _buildGlobalCacheKey(null, clusterName, tableName);
try {
redisClient = jedisPool.getResource();
Collection<Jedis> shards = redisClient.getAllShards();
Set<String> keys = null;
for (Jedis shard : shards) {
keys = shard.keys(cacheKey);
if (keys != null && !keys.isEmpty())
shard.del(keys.toArray(new String[keys.size()]));
}
if (LOG.isDebugEnabled()) {
LOG.debug("[SECOND CACHE] - " + cacheKey + " clean");
}
} catch (Exception e) {
LOG.warn("remove second cache failure");
} finally {
if (redisClient != null)
redisClient.close();
}
}
@Override
public void put(String whereKey, ShardingDBResource db, List data) {
if (StringUtil.isBlank(whereKey) || data == null || data.isEmpty()) {
return;
}
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
String cacheKey = _buildShardingCacheKey(whereKey, db);
redisClient.set(cacheKey.getBytes(), IOUtil.getBytes(data));
redisClient.expire(cacheKey.getBytes(), expire);
if (LOG.isDebugEnabled()) {
LOG.debug("[SECOND CACHE] - put to cache done, key: " + cacheKey);
}
} catch (Exception e) {
LOG.warn("operate second cache failure");
} finally {
if (redisClient != null)
redisClient.close();
}
}
@Override
public List get(String whereKey, ShardingDBResource db) {
if (StringUtil.isBlank(whereKey)) {
return null;
}
ShardedJedis redisClient = null;
try {
redisClient = jedisPool.getResource();
String cacheKey = _buildShardingCacheKey(whereKey, db);
List data = IOUtil.getObject(redisClient.get(cacheKey.getBytes()), List.class);
if (LOG.isDebugEnabled() && data != null) {
LOG.debug("[SECOND CACHE] - key " + cacheKey + " hit");
}
return data;
} catch (Exception e) {
LOG.warn("operate second cache failure");
} finally {
if (redisClient != null)
redisClient.close();
}
return null;
}
@Override
public void remove(ShardingDBResource db) {
ShardedJedis redisClient = null;
String cacheKey = _buildShardingCacheKey(null, db);
try {
redisClient = jedisPool.getResource();
Collection<Jedis> shards = redisClient.getAllShards();
Set<String> keys = null;
for (Jedis shard : shards) {
keys = shard.keys(cacheKey);
if (keys != null && !keys.isEmpty())
shard.del(keys.toArray(new String[keys.size()]));
}
if (LOG.isDebugEnabled()) {
LOG.debug("[SECOND CACHE] - " + cacheKey + " clean");
}
} catch (Exception e) {
LOG.warn("remove second cache failure " + cacheKey);
} finally {
if (redisClient != null)
redisClient.close();
}
}
/**
* global second cache key. sec.[clustername].[tablename].hashCode
*/
private String _buildGlobalCacheKey(String whereKey, String clusterName, String tableName) {
StringBuilder cacheKey = new StringBuilder("sec.");
cacheKey.append(clusterName).append(".");
cacheKey.append(tableName);
cacheKey.append(".");
cacheKey.append(getCacheVersion(tableName));
cacheKey.append(".");
if (StringUtil.isNotBlank(whereKey))
cacheKey.append(SecurityUtil.md5(whereKey));
else
cacheKey.append("*");
return cacheKey.toString();
}
/**
* sharding second cache key. sec.[clustername].[startend].[tablename +
* tableIndex].hashCode
*/
private String _buildShardingCacheKey(String whereKey, ShardingDBResource shardingDBResource) {
StringBuilder cacheKey = new StringBuilder("sec.");
cacheKey.append(shardingDBResource.getClusterName());
cacheKey.append(".");
cacheKey.append(shardingDBResource.getDbName());
cacheKey.append(".");
cacheKey.append(shardingDBResource.getRegionCapacity());
cacheKey.append(".");
cacheKey.append(shardingDBResource.getTableName()).append(shardingDBResource.getTableIndex());
cacheKey.append(".");
cacheKey.append(getCacheVersion(shardingDBResource.getTableName()));
cacheKey.append(".");
if (StringUtil.isNotBlank(whereKey))
cacheKey.append(SecurityUtil.md5(whereKey));
else
cacheKey.append("*");
return cacheKey.toString();
}
}