Replace synchronized keyword lock to ReaderWriterLock

This commit is contained in:
Jungtaek Lim
2014-07-02 23:46:15 +09:00
parent 94966e6163
commit 4b72a4d254

View File

@@ -8,6 +8,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class JedisClusterInfoCache { public class JedisClusterInfoCache {
public static final ClusterNodeInformationParser nodeInfoParser = new ClusterNodeInformationParser(); public static final ClusterNodeInformationParser nodeInfoParser = new ClusterNodeInformationParser();
@@ -15,7 +17,14 @@ public class JedisClusterInfoCache {
private Map<String, JedisPool> nodes = new HashMap<String, JedisPool>(); private Map<String, JedisPool> nodes = new HashMap<String, JedisPool>();
private Map<Integer, JedisPool> slots = new HashMap<Integer, JedisPool>(); private Map<Integer, JedisPool> slots = new HashMap<Integer, JedisPool>();
public synchronized void discoverClusterNodesAndSlots(Jedis jedis) { private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
public void discoverClusterNodesAndSlots(Jedis jedis) {
w.lock();
try {
this.nodes.clear(); this.nodes.clear();
this.slots.clear(); this.slots.clear();
@@ -29,9 +38,15 @@ public class JedisClusterInfoCache {
setNodeIfNotExist(targetNode); setNodeIfNotExist(targetNode);
assignSlotsToNode(clusterNodeInfo.getAvailableSlots(), targetNode); assignSlotsToNode(clusterNodeInfo.getAvailableSlots(), targetNode);
} }
} finally {
w.unlock();
}
} }
public synchronized void discoverClusterSlots(Jedis jedis) { public void discoverClusterSlots(Jedis jedis) {
w.lock();
try {
this.slots.clear(); this.slots.clear();
List<Object> slots = jedis.clusterSlots(); List<Object> slots = jedis.clusterSlots();
@@ -43,13 +58,7 @@ public class JedisClusterInfoCache {
continue; continue;
} }
// assigned slots List<Integer> slotNums = getAssignedSlotArray(slotInfo);
List<Integer> slotNums = new ArrayList<Integer>();
for (int slot = ((Long) slotInfo.get(0)).intValue() ;
slot <= ((Long) slotInfo.get(1)).intValue() ;
slot++) {
slotNums.add(slot);
}
// hostInfos // hostInfos
List<Object> hostInfos = (List<Object>) slotInfo.get(2); List<Object> hostInfos = (List<Object>) slotInfo.get(2);
@@ -58,25 +67,39 @@ public class JedisClusterInfoCache {
} }
// at this time, we just use master, discard slave information // at this time, we just use master, discard slave information
HostAndPort targetNode = new HostAndPort( HostAndPort targetNode = generateHostAndPort(hostInfos);
SafeEncoder.encode((byte[]) hostInfos.get(0)),
((Long) hostInfos.get(1)).intValue());
setNodeIfNotExist(targetNode); setNodeIfNotExist(targetNode);
assignSlotsToNode(slotNums, targetNode); assignSlotsToNode(slotNums, targetNode);
} }
} finally {
w.unlock();
}
} }
public synchronized void setNodeIfNotExist(HostAndPort node) { private HostAndPort generateHostAndPort(List<Object> hostInfos) {
return new HostAndPort(
SafeEncoder.encode((byte[]) hostInfos.get(0)),
((Long) hostInfos.get(1)).intValue());
}
public void setNodeIfNotExist(HostAndPort node) {
w.lock();
try {
String nodeKey = getNodeKey(node); String nodeKey = getNodeKey(node);
if (nodes.containsKey(nodeKey)) if (nodes.containsKey(nodeKey))
return; return;
JedisPool nodePool = new JedisPool(node.getHost(), node.getPort()); JedisPool nodePool = new JedisPool(node.getHost(), node.getPort());
nodes.put(nodeKey, nodePool); nodes.put(nodeKey, nodePool);
} finally {
w.unlock();
}
} }
public synchronized void assignSlotToNode(int slot, HostAndPort targetNode) { public void assignSlotToNode(int slot, HostAndPort targetNode) {
w.lock();
try {
JedisPool targetPool = nodes.get(getNodeKey(targetNode)); JedisPool targetPool = nodes.get(getNodeKey(targetNode));
if (targetPool == null) { if (targetPool == null) {
@@ -84,10 +107,15 @@ public class JedisClusterInfoCache {
targetPool = nodes.get(getNodeKey(targetNode)); targetPool = nodes.get(getNodeKey(targetNode));
} }
slots.put(slot, targetPool); slots.put(slot, targetPool);
} finally {
w.unlock();
}
} }
public synchronized void assignSlotsToNode(List<Integer> targetSlots, public synchronized void assignSlotsToNode(List<Integer> targetSlots,
HostAndPort targetNode) { HostAndPort targetNode) {
w.lock();
try {
JedisPool targetPool = nodes.get(getNodeKey(targetNode)); JedisPool targetPool = nodes.get(getNodeKey(targetNode));
if (targetPool == null) { if (targetPool == null) {
@@ -98,18 +126,36 @@ public class JedisClusterInfoCache {
for (Integer slot : targetSlots) { for (Integer slot : targetSlots) {
slots.put(slot, targetPool); slots.put(slot, targetPool);
} }
} finally {
w.unlock();
}
} }
public synchronized JedisPool getNode(String nodeKey) { public synchronized JedisPool getNode(String nodeKey) {
r.lock();
try {
return nodes.get(nodeKey); return nodes.get(nodeKey);
} finally {
r.unlock();
}
} }
public synchronized JedisPool getSlotPool(int slot) { public synchronized JedisPool getSlotPool(int slot) {
r.lock();
try {
return slots.get(slot); return slots.get(slot);
} finally {
r.unlock();
}
} }
public synchronized Map<String, JedisPool> getNodes() { public synchronized Map<String, JedisPool> getNodes() {
r.lock();
try {
return new HashMap<String, JedisPool>(nodes); return new HashMap<String, JedisPool>(nodes);
} finally {
r.unlock();
}
} }
public static String getNodeKey(HostAndPort hnp) { public static String getNodeKey(HostAndPort hnp) {
@@ -124,4 +170,14 @@ public class JedisClusterInfoCache {
return getNodeKey(jedis.getClient()); return getNodeKey(jedis.getClient());
} }
private List<Integer> getAssignedSlotArray(List<Object> slotInfo) {
List<Integer> slotNums = new ArrayList<Integer>();
for (int slot = ((Long) slotInfo.get(0)).intValue();
slot <= ((Long) slotInfo.get(1)).intValue();
slot++) {
slotNums.add(slot);
}
return slotNums;
}
} }