You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ma...@apache.org on 2012/08/04 23:42:42 UTC

svn commit: r1369480 - in /lucene/dev/branches/branch_4x: ./ solr/ solr/core/ solr/core/src/test/org/apache/solr/cloud/ solr/solrj/ solr/solrj/src/java/org/apache/solr/client/solrj/impl/ solr/solrj/src/java/org/apache/solr/common/cloud/

Author: markrmiller
Date: Sat Aug  4 21:42:42 2012
New Revision: 1369480

URL: http://svn.apache.org/viewvc?rev=1369480&view=rev
Log:
SOLR-3709: Cache the url list created from the ClusterState in CloudSolrServer on each request.
SOLR-3708: Add hashcode to ClusterState so that structures built based on the ClusterState can be easily cached.	

Modified:
    lucene/dev/branches/branch_4x/   (props changed)
    lucene/dev/branches/branch_4x/solr/   (props changed)
    lucene/dev/branches/branch_4x/solr/CHANGES.txt   (contents, props changed)
    lucene/dev/branches/branch_4x/solr/core/   (props changed)
    lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java
    lucene/dev/branches/branch_4x/solr/solrj/   (props changed)
    lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java
    lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
    lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java

Modified: lucene/dev/branches/branch_4x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/CHANGES.txt?rev=1369480&r1=1369479&r2=1369480&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/solr/CHANGES.txt Sat Aug  4 21:42:42 2012
@@ -105,6 +105,15 @@ New Features
 * SOLR-3672: SimplePostTool: Improvements for posting files
   Support for auto mode, recursive and wildcards (janhoy)
 
+Optimizations
+----------------------
+
+* SOLR-3708: Add hashCode to ClusterState so that structures built based on the 
+  ClusterState can be easily cached. (Mark Miller)
+
+* SOLR-3709: Cache the url list created from the ClusterState in CloudSolrServer on each 
+  request. (Mark Miller, yonik)
+
 Bug Fixes
 ----------------------
 

Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java?rev=1369480&r1=1369479&r2=1369480&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ClusterStateTest.java Sat Aug  4 21:42:42 2012
@@ -55,7 +55,7 @@ public class ClusterStateTest extends So
     ClusterState clusterState = new ClusterState(liveNodes, collectionStates);
     byte[] bytes = ZkStateReader.toJSON(clusterState);
     
-    ClusterState loadedClusterState = ClusterState.load(bytes, liveNodes);
+    ClusterState loadedClusterState = ClusterState.load(null, bytes, liveNodes);
     
     assertEquals("Provided liveNodes not used properly", 2, loadedClusterState
         .getLiveNodes().size());
@@ -63,13 +63,13 @@ public class ClusterStateTest extends So
     assertEquals("Poperties not copied properly", zkNodeProps.get("prop1"), loadedClusterState.getSlice("collection1", "shard1").getShards().get("node1").get("prop1"));
     assertEquals("Poperties not copied properly", zkNodeProps.get("prop2"), loadedClusterState.getSlice("collection1", "shard1").getShards().get("node1").get("prop2"));
 
-    loadedClusterState = ClusterState.load(new byte[0], liveNodes);
+    loadedClusterState = ClusterState.load(null, new byte[0], liveNodes);
     
     assertEquals("Provided liveNodes not used properly", 2, loadedClusterState
         .getLiveNodes().size());
     assertEquals("Should not have collections", 0, loadedClusterState.getCollections().size());
 
-    loadedClusterState = ClusterState.load((byte[])null, liveNodes);
+    loadedClusterState = ClusterState.load(null, (byte[])null, liveNodes);
     
     assertEquals("Provided liveNodes not used properly", 2, loadedClusterState
         .getLiveNodes().size());

Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java?rev=1369480&r1=1369479&r2=1369480&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java Sat Aug  4 21:42:42 2012
@@ -61,6 +61,10 @@ public class CloudSolrServer extends Sol
   private LBHttpSolrServer lbServer;
   private HttpClient myClient;
   Random rand = new Random();
+  
+  // since the state shouldn't change often, should be very cheap reads
+  private volatile List<String> urlList;
+  private volatile int lastClusterStateHashCode;
   /**
    * @param zkHost The client endpoint of the zookeeper quorum containing the cloud state,
    * in the form HOST:PORT.
@@ -168,22 +172,26 @@ public class CloudSolrServer extends Sol
     // or shardAddressVersion (which only changes when the shards change)
     // to allow caching.
 
-    // build a map of unique nodes
-    // TODO: allow filtering by group, role, etc
-    Map<String,ZkNodeProps> nodes = new HashMap<String,ZkNodeProps>();
-    List<String> urlList = new ArrayList<String>();
-    for (Slice slice : slices.values()) {
-      for (ZkNodeProps nodeProps : slice.getShards().values()) {
-        ZkCoreNodeProps coreNodeProps = new ZkCoreNodeProps(nodeProps);
-        String node = coreNodeProps.getNodeName();
-        if (!liveNodes.contains(coreNodeProps.getNodeName())
-            || !coreNodeProps.getState().equals(
-                ZkStateReader.ACTIVE)) continue;
-        if (nodes.put(node, nodeProps) == null) {
-          String url = coreNodeProps.getCoreUrl();
-          urlList.add(url);
+    if (clusterState.hashCode() != this.lastClusterStateHashCode) {
+    
+      // build a map of unique nodes
+      // TODO: allow filtering by group, role, etc
+      Map<String,ZkNodeProps> nodes = new HashMap<String,ZkNodeProps>();
+      List<String> urlList = new ArrayList<String>();
+      for (Slice slice : slices.values()) {
+        for (ZkNodeProps nodeProps : slice.getShards().values()) {
+          ZkCoreNodeProps coreNodeProps = new ZkCoreNodeProps(nodeProps);
+          String node = coreNodeProps.getNodeName();
+          if (!liveNodes.contains(coreNodeProps.getNodeName())
+              || !coreNodeProps.getState().equals(ZkStateReader.ACTIVE)) continue;
+          if (nodes.put(node, nodeProps) == null) {
+            String url = coreNodeProps.getCoreUrl();
+            urlList.add(url);
+          }
         }
       }
+      this.urlList = urlList;
+      this.lastClusterStateHashCode = clusterState.hashCode();
     }
 
     Collections.shuffle(urlList, rand);

Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java?rev=1369480&r1=1369479&r2=1369480&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java Sat Aug  4 21:42:42 2012
@@ -32,6 +32,7 @@ import org.apache.solr.common.SolrExcept
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.cloud.HashPartitioner.Range;
 import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -42,25 +43,49 @@ import org.slf4j.LoggerFactory;
 public class ClusterState implements JSONWriter.Writable {
   private static Logger log = LoggerFactory.getLogger(ClusterState.class);
   
-	private final Map<String, Map<String,Slice>> collectionStates;  // Map<collectionName, Map<sliceName,Slice>>
-	private final Set<String> liveNodes;
+  private Integer zkClusterStateVersion;
+  
+  private final Map<String, Map<String,Slice>> collectionStates;  // Map<collectionName, Map<sliceName,Slice>>
+  private final Set<String> liveNodes;
   
   private final HashPartitioner hp = new HashPartitioner();
   
   private final Map<String,RangeInfo> rangeInfos = new HashMap<String,RangeInfo>();
   private final Map<String,Map<String,ZkNodeProps>> leaders = new HashMap<String,Map<String,ZkNodeProps>>();
 
-	public ClusterState(Set<String> liveNodes,
-			Map<String, Map<String,Slice>> collectionStates) {
-		this.liveNodes = new HashSet<String>(liveNodes.size());
-		this.liveNodes.addAll(liveNodes);
-		this.collectionStates = new HashMap<String, Map<String,Slice>>(collectionStates.size());
-		this.collectionStates.putAll(collectionStates);
-		addRangeInfos(collectionStates.keySet());
-		getShardLeaders();
-	}
 
-	private void getShardLeaders() {
+  
+  /**
+   * Use this constr when ClusterState is meant for publication.
+   * 
+   * hashCode and equals will only depend on liveNodes and not clusterStateVersion.
+   * 
+   * @param liveNodes
+   * @param collectionStates
+   */
+  public ClusterState(Set<String> liveNodes,
+      Map<String, Map<String,Slice>> collectionStates) {
+    this(null, liveNodes, collectionStates);
+  }
+  
+  /**
+   * Use this constr when ClusterState is meant for consumption.
+   * 
+   * @param zkClusterStateVersion
+   * @param liveNodes
+   * @param collectionStates
+   */
+  public ClusterState(Integer zkClusterStateVersion, Set<String> liveNodes,
+      Map<String, Map<String,Slice>> collectionStates) {
+    this.liveNodes = new HashSet<String>(liveNodes.size());
+    this.liveNodes.addAll(liveNodes);
+    this.collectionStates = new HashMap<String, Map<String,Slice>>(collectionStates.size());
+    this.collectionStates.putAll(collectionStates);
+    addRangeInfos(collectionStates.keySet());
+    getShardLeaders();
+  }
+
+  private void getShardLeaders() {
     Set<Entry<String,Map<String,Slice>>> collections = collectionStates.entrySet();
     for (Entry<String,Map<String,Slice>> collection : collections) {
       Map<String,Slice> state = collection.getValue();
@@ -85,27 +110,27 @@ public class ClusterState implements JSO
     }
   }
 
-	/**
-	 * Get properties of a shard leader for specific collection.
-	 */
-	public ZkNodeProps getLeader(String collection, String shard) {
-	  Map<String,ZkNodeProps> collectionLeaders = leaders.get(collection);
-	  if (collectionLeaders == null) return null;
-	  return collectionLeaders.get(shard);
-	}
-	
-	/**
-	 * Get shard properties or null if shard is not found.
-	 */
-	public ZkNodeProps getShardProps(final String collection, final String coreNodeName) {
-	  Map<String, Slice> slices = getSlices(collection);
-	  for(Slice slice: slices.values()) {
-	    if(slice.getShards().get(coreNodeName)!=null) {
-	      return slice.getShards().get(coreNodeName);
-	    }
-	  }
-	  return null;
-	}
+  /**
+   * Get properties of a shard leader for specific collection.
+   */
+  public ZkNodeProps getLeader(String collection, String shard) {
+    Map<String,ZkNodeProps> collectionLeaders = leaders.get(collection);
+    if (collectionLeaders == null) return null;
+    return collectionLeaders.get(shard);
+  }
+  
+  /**
+   * Get shard properties or null if shard is not found.
+   */
+  public ZkNodeProps getShardProps(final String collection, final String coreNodeName) {
+    Map<String, Slice> slices = getSlices(collection);
+    for(Slice slice: slices.values()) {
+      if(slice.getShards().get(coreNodeName)!=null) {
+        return slice.getShards().get(coreNodeName);
+      }
+    }
+    return null;
+  }
 
   private void addRangeInfos(Set<String> collections) {
     for (String collection : collections) {
@@ -117,72 +142,72 @@ public class ClusterState implements JSO
    * Get the index Slice for collection.
    */
   public Slice getSlice(String collection, String slice) {
-		if (collectionStates.containsKey(collection)
-				&& collectionStates.get(collection).containsKey(slice))
-			return collectionStates.get(collection).get(slice);
-		return null;
-	}
+    if (collectionStates.containsKey(collection)
+        && collectionStates.get(collection).containsKey(slice))
+      return collectionStates.get(collection).get(slice);
+    return null;
+  }
 
   /**
    * Get all slices for collection.
    */
-	public Map<String, Slice> getSlices(String collection) {
-		if(!collectionStates.containsKey(collection))
-			return null;
-		return Collections.unmodifiableMap(collectionStates.get(collection));
-	}
-
-	/**
-	 * Get collection names.
-	 */
-	public Set<String> getCollections() {
-		return Collections.unmodifiableSet(collectionStates.keySet());
-	}
-
-	/**
-	 * @return Map&lt;collectionName, Map&lt;sliceName,Slice&gt;&gt;
-	 */
-	public Map<String, Map<String, Slice>> getCollectionStates() {
-		return Collections.unmodifiableMap(collectionStates);
-	}
-
-	/**
-	 * Get names of the currently live nodes.
-	 */
-	public Set<String> getLiveNodes() {
-		return Collections.unmodifiableSet(liveNodes);
-	}
-
-	/**
-	 * Get shardId for core.
-	 * @param coreNodeName in the form of nodeName_coreName
-	 */
-	public String getShardId(String coreNodeName) {
-	  for (Entry<String, Map<String, Slice>> states: collectionStates.entrySet()){
-	    for(Entry<String, Slice> slices: states.getValue().entrySet()) {
-	      for(Entry<String, ZkNodeProps> shards: slices.getValue().getShards().entrySet()){
-	        if(coreNodeName.equals(shards.getKey())) {
-	          return slices.getKey();
-	        }
-	      }
-	    }
-	  }
-	  return null;
-	}
-
-	/**
-	 * Check if node is alive. 
-	 */
-	public boolean liveNodesContain(String name) {
-		return liveNodes.contains(name);
-	}
-	
-	public RangeInfo getRanges(String collection) {
+  public Map<String, Slice> getSlices(String collection) {
+    if(!collectionStates.containsKey(collection))
+      return null;
+    return Collections.unmodifiableMap(collectionStates.get(collection));
+  }
+
+  /**
+   * Get collection names.
+   */
+  public Set<String> getCollections() {
+    return Collections.unmodifiableSet(collectionStates.keySet());
+  }
+
+  /**
+   * @return Map&lt;collectionName, Map&lt;sliceName,Slice&gt;&gt;
+   */
+  public Map<String, Map<String, Slice>> getCollectionStates() {
+    return Collections.unmodifiableMap(collectionStates);
+  }
+
+  /**
+   * Get names of the currently live nodes.
+   */
+  public Set<String> getLiveNodes() {
+    return Collections.unmodifiableSet(liveNodes);
+  }
+
+  /**
+   * Get shardId for core.
+   * @param coreNodeName in the form of nodeName_coreName
+   */
+  public String getShardId(String coreNodeName) {
+    for (Entry<String, Map<String, Slice>> states: collectionStates.entrySet()){
+      for(Entry<String, Slice> slices: states.getValue().entrySet()) {
+        for(Entry<String, ZkNodeProps> shards: slices.getValue().getShards().entrySet()){
+          if(coreNodeName.equals(shards.getKey())) {
+            return slices.getKey();
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Check if node is alive. 
+   */
+  public boolean liveNodesContain(String name) {
+    return liveNodes.contains(name);
+  }
+  
+  public RangeInfo getRanges(String collection) {
     // TODO: store this in zk
     RangeInfo rangeInfo = rangeInfos.get(collection);
 
-	  return rangeInfo;
-	}
+    return rangeInfo;
+  }
 
   private RangeInfo addRangeInfo(String collection) {
     List<Range> ranges;
@@ -227,29 +252,39 @@ public class ClusterState implements JSO
     throw new IllegalStateException("The HashPartitioner failed");
   }
 
-	@Override
-	public String toString() {
-		StringBuilder sb = new StringBuilder();
-		sb.append("live nodes:" + liveNodes);
-		sb.append(" collections:" + collectionStates);
-		return sb.toString();
-	}
-
-	/**
-	 * Create ClusterState by reading the current state from zookeeper. 
-	 */
-	public static ClusterState load(SolrZkClient zkClient, Set<String> liveNodes) throws KeeperException, InterruptedException {
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder();
+    sb.append("live nodes:" + liveNodes);
+    sb.append(" collections:" + collectionStates);
+    return sb.toString();
+  }
+
+  /**
+   * Create ClusterState by reading the current state from zookeeper. 
+   */
+  public static ClusterState load(SolrZkClient zkClient, Set<String> liveNodes) throws KeeperException, InterruptedException {
+    Stat stat = new Stat();
     byte[] state = zkClient.getData(ZkStateReader.CLUSTER_STATE,
-        null, null, true);
-    return load(state, liveNodes);
-	}
-	
-	/**
-	 * Create ClusterState from json string that is typically stored in zookeeper.
-	 */
-	public static ClusterState load(byte[] bytes, Set<String> liveNodes) {
+        null, stat, true);
+    return load(stat.getVersion(), state, liveNodes);
+  }
+  
+ 
+  /**
+   * Create ClusterState from json string that is typically stored in zookeeper.
+   * 
+   * Use {@link ClusterState#load(SolrZkClient, Set)} instead, unless you want to
+   * do something more when getting the data - such as get the stat, set watch, etc.
+   * 
+   * @param version zk version of the clusterstate.json file (bytes)
+   * @param bytes clusterstate.json as a byte array
+   * @param liveNodes list of live nodes
+   * @return the ClusterState
+   */
+  public static ClusterState load(Integer version, byte[] bytes, Set<String> liveNodes) {
     if (bytes == null || bytes.length == 0) {
-      return new ClusterState(liveNodes, Collections.<String, Map<String,Slice>>emptyMap());
+      return new ClusterState(version, liveNodes, Collections.<String, Map<String,Slice>>emptyMap());
     }
     
     LinkedHashMap<String, Object> stateMap = (LinkedHashMap<String, Object>) ZkStateReader.fromJSON(bytes);
@@ -269,8 +304,8 @@ public class ClusterState implements JSO
       }
       state.put(collectionName, slices);
     }
-    return new ClusterState(liveNodes, state);
-	}
+    return new ClusterState(version, liveNodes, state);
+  }
 
   @Override
   public void write(JSONWriter jsonWriter) {
@@ -282,5 +317,41 @@ public class ClusterState implements JSO
     private ArrayList<String> shardList;
   }
 
+  /**
+   * The version of clusterstate.json in ZooKeeper.
+   * 
+   * @return null if ClusterState was created for publication, not consumption
+   */
+  public Integer getZkClusterStateVersion() {
+    return zkClusterStateVersion;
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result
+        + ((zkClusterStateVersion == null) ? 0 : zkClusterStateVersion.hashCode());
+    result = prime * result + ((liveNodes == null) ? 0 : liveNodes.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) return true;
+    if (obj == null) return false;
+    if (getClass() != obj.getClass()) return false;
+    ClusterState other = (ClusterState) obj;
+    if (zkClusterStateVersion == null) {
+      if (other.zkClusterStateVersion != null) return false;
+    } else if (!zkClusterStateVersion.equals(other.zkClusterStateVersion)) return false;
+    if (liveNodes == null) {
+      if (other.liveNodes != null) return false;
+    } else if (!liveNodes.equals(other.liveNodes)) return false;
+    return true;
+  }
+
+
+
 
 }

Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java?rev=1369480&r1=1369479&r2=1369480&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java Sat Aug  4 21:42:42 2012
@@ -42,6 +42,7 @@ import org.apache.zookeeper.KeeperExcept
 import org.apache.zookeeper.WatchedEvent;
 import org.apache.zookeeper.Watcher;
 import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.data.Stat;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -193,10 +194,11 @@ public class ZkStateReader {
             synchronized (ZkStateReader.this.getUpdateLock()) {
               // remake watch
               final Watcher thisWatch = this;
-              byte[] data = zkClient.getData(CLUSTER_STATE, thisWatch, null,
+              Stat stat = new Stat();
+              byte[] data = zkClient.getData(CLUSTER_STATE, thisWatch, stat ,
                   true);
               
-              ClusterState clusterState = ClusterState.load(data,
+              ClusterState clusterState = ClusterState.load(stat.getVersion(), data,
                   ZkStateReader.this.clusterState.getLiveNodes());
               // update volatile
               ZkStateReader.this.clusterState = clusterState;
@@ -242,8 +244,10 @@ public class ZkStateReader {
                       LIVE_NODES_ZKNODE, this, true);
                   Set<String> liveNodesSet = new HashSet<String>();
                   liveNodesSet.addAll(liveNodes);
-                  ClusterState clusterState = new ClusterState(liveNodesSet,
-                      ZkStateReader.this.clusterState.getCollectionStates());
+                  ClusterState clusterState = new ClusterState(
+                      ZkStateReader.this.clusterState.getZkClusterStateVersion(),
+                      liveNodesSet, ZkStateReader.this.clusterState
+                          .getCollectionStates());
                   ZkStateReader.this.clusterState = clusterState;
                 }
               } catch (KeeperException e) {
@@ -293,7 +297,8 @@ public class ZkStateReader {
           clusterState = ClusterState.load(zkClient, liveNodesSet);
         } else {
           log.info("Updating live nodes from ZooKeeper... ");
-          clusterState = new ClusterState(liveNodesSet,
+          clusterState = new ClusterState(
+              ZkStateReader.this.clusterState.getZkClusterStateVersion(), liveNodesSet,
               ZkStateReader.this.clusterState.getCollectionStates());
         }
       }
@@ -325,7 +330,7 @@ public class ZkStateReader {
                 clusterState = ClusterState.load(zkClient, liveNodesSet);
               } else {
                 log.info("Updating live nodes from ZooKeeper... ");
-                clusterState = new ClusterState(liveNodesSet, ZkStateReader.this.clusterState.getCollectionStates());
+                clusterState = new ClusterState(ZkStateReader.this.clusterState .getZkClusterStateVersion(), liveNodesSet, ZkStateReader.this.clusterState.getCollectionStates());
               }
               
               ZkStateReader.this.clusterState = clusterState;