From 4b72a4d25492ad4664e857006643e3bd8a361fff Mon Sep 17 00:00:00 2001 From: Jungtaek Lim Date: Wed, 2 Jul 2014 23:46:15 +0900 Subject: [PATCH] Replace synchronized keyword lock to ReaderWriterLock --- .../clients/jedis/JedisClusterInfoCache.java | 182 ++++++++++++------ 1 file changed, 119 insertions(+), 63 deletions(-) diff --git a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java index 7c1f491..0906b5e 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java +++ b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java @@ -8,6 +8,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; public class JedisClusterInfoCache { public static final ClusterNodeInformationParser nodeInfoParser = new ClusterNodeInformationParser(); @@ -15,101 +17,145 @@ public class JedisClusterInfoCache { private Map nodes = new HashMap(); private Map slots = new HashMap(); - public synchronized void discoverClusterNodesAndSlots(Jedis jedis) { - this.nodes.clear(); - this.slots.clear(); + private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + private final Lock r = rwl.readLock(); + private final Lock w = rwl.writeLock(); - String localNodes = jedis.clusterNodes(); - for (String nodeInfo : localNodes.split("\n")) { - ClusterNodeInformation clusterNodeInfo = nodeInfoParser.parse( - nodeInfo, new HostAndPort(jedis.getClient().getHost(), - jedis.getClient().getPort())); + public void discoverClusterNodesAndSlots(Jedis jedis) { + w.lock(); - HostAndPort targetNode = clusterNodeInfo.getNode(); - setNodeIfNotExist(targetNode); - assignSlotsToNode(clusterNodeInfo.getAvailableSlots(), targetNode); + try { + this.nodes.clear(); + this.slots.clear(); + + String localNodes = jedis.clusterNodes(); + for (String nodeInfo : localNodes.split("\n")) { + ClusterNodeInformation clusterNodeInfo = nodeInfoParser.parse( + nodeInfo, new HostAndPort(jedis.getClient().getHost(), + jedis.getClient().getPort())); + + HostAndPort targetNode = clusterNodeInfo.getNode(); + setNodeIfNotExist(targetNode); + assignSlotsToNode(clusterNodeInfo.getAvailableSlots(), targetNode); + } + } finally { + w.unlock(); } } - public synchronized void discoverClusterSlots(Jedis jedis) { - this.slots.clear(); + public void discoverClusterSlots(Jedis jedis) { + w.lock(); - List slots = jedis.clusterSlots(); + try { + this.slots.clear(); - for (Object slotInfoObj : slots) { - List slotInfo = (List) slotInfoObj; + List slots = jedis.clusterSlots(); - if (slotInfo.size() <= 2) { - continue; + for (Object slotInfoObj : slots) { + List slotInfo = (List) slotInfoObj; + + if (slotInfo.size() <= 2) { + continue; + } + + List slotNums = getAssignedSlotArray(slotInfo); + + // hostInfos + List hostInfos = (List) slotInfo.get(2); + if (hostInfos.size() <= 0) { + continue; + } + + // at this time, we just use master, discard slave information + HostAndPort targetNode = generateHostAndPort(hostInfos); + + setNodeIfNotExist(targetNode); + assignSlotsToNode(slotNums, targetNode); } - - // assigned slots - List slotNums = new ArrayList(); - for (int slot = ((Long) slotInfo.get(0)).intValue() ; - slot <= ((Long) slotInfo.get(1)).intValue() ; - slot++) { - slotNums.add(slot); - } - - // hostInfos - List hostInfos = (List) slotInfo.get(2); - if (hostInfos.size() <= 0) { - continue; - } - - // at this time, we just use master, discard slave information - HostAndPort targetNode = new HostAndPort( - SafeEncoder.encode((byte[]) hostInfos.get(0)), - ((Long) hostInfos.get(1)).intValue()); - - setNodeIfNotExist(targetNode); - assignSlotsToNode(slotNums, targetNode); + } finally { + w.unlock(); } } - public synchronized void setNodeIfNotExist(HostAndPort node) { - String nodeKey = getNodeKey(node); - if (nodes.containsKey(nodeKey)) - return; - - JedisPool nodePool = new JedisPool(node.getHost(), node.getPort()); - nodes.put(nodeKey, nodePool); + private HostAndPort generateHostAndPort(List hostInfos) { + return new HostAndPort( + SafeEncoder.encode((byte[]) hostInfos.get(0)), + ((Long) hostInfos.get(1)).intValue()); } - public synchronized void assignSlotToNode(int slot, HostAndPort targetNode) { - JedisPool targetPool = nodes.get(getNodeKey(targetNode)); + public void setNodeIfNotExist(HostAndPort node) { + w.lock(); + try { + String nodeKey = getNodeKey(node); + if (nodes.containsKey(nodeKey)) + return; - if (targetPool == null) { - setNodeIfNotExist(targetNode); - targetPool = nodes.get(getNodeKey(targetNode)); + JedisPool nodePool = new JedisPool(node.getHost(), node.getPort()); + nodes.put(nodeKey, nodePool); + } finally { + w.unlock(); + } + } + + public void assignSlotToNode(int slot, HostAndPort targetNode) { + w.lock(); + try { + JedisPool targetPool = nodes.get(getNodeKey(targetNode)); + + if (targetPool == null) { + setNodeIfNotExist(targetNode); + targetPool = nodes.get(getNodeKey(targetNode)); + } + slots.put(slot, targetPool); + } finally { + w.unlock(); } - slots.put(slot, targetPool); } public synchronized void assignSlotsToNode(List targetSlots, HostAndPort targetNode) { - JedisPool targetPool = nodes.get(getNodeKey(targetNode)); + w.lock(); + try { + JedisPool targetPool = nodes.get(getNodeKey(targetNode)); - if (targetPool == null) { - setNodeIfNotExist(targetNode); - targetPool = nodes.get(getNodeKey(targetNode)); - } + if (targetPool == null) { + setNodeIfNotExist(targetNode); + targetPool = nodes.get(getNodeKey(targetNode)); + } - for (Integer slot : targetSlots) { - slots.put(slot, targetPool); + for (Integer slot : targetSlots) { + slots.put(slot, targetPool); + } + } finally { + w.unlock(); } } public synchronized JedisPool getNode(String nodeKey) { - return nodes.get(nodeKey); + r.lock(); + try { + return nodes.get(nodeKey); + } finally { + r.unlock(); + } } public synchronized JedisPool getSlotPool(int slot) { - return slots.get(slot); + r.lock(); + try { + return slots.get(slot); + } finally { + r.unlock(); + } } public synchronized Map getNodes() { - return new HashMap(nodes); + r.lock(); + try { + return new HashMap(nodes); + } finally { + r.unlock(); + } } public static String getNodeKey(HostAndPort hnp) { @@ -124,4 +170,14 @@ public class JedisClusterInfoCache { return getNodeKey(jedis.getClient()); } + private List getAssignedSlotArray(List slotInfo) { + List slotNums = new ArrayList(); + for (int slot = ((Long) slotInfo.get(0)).intValue(); + slot <= ((Long) slotInfo.get(1)).intValue(); + slot++) { + slotNums.add(slot); + } + return slotNums; + } + }