/// <summary> /// Remove nodes using copy on write semantics. /// </summary> private void RemoveNodesCopy(List <Node> nodesToRemove) { // Create temporary nodes array. // Since nodes are only marked for deletion using node references in the nodes array, // and the tend thread is the only thread modifying nodes, we are guaranteed that nodes // in nodesToRemove exist. Therefore, we know the final array size. Node[] nodeArray = new Node[nodes.Length - nodesToRemove.Count]; int count = 0; // Add nodes that are not in remove list. foreach (Node node in nodes) { if (FindNode(node, nodesToRemove)) { if (tendValid && Log.InfoEnabled()) { Log.Info("Remove node " + node); } } else { nodeArray[count++] = node; } } // Do sanity check to make sure assumptions are correct. if (count < nodeArray.Length) { if (Log.WarnEnabled()) { Log.Warn("Node remove mismatch. Expected " + nodeArray.Length + " Received " + count); } // Resize array. Node[] nodeArray2 = new Node[count]; Array.Copy(nodeArray, 0, nodeArray2, 0, count); nodeArray = nodeArray2; } hasPartitionScan = Cluster.SupportsPartitionScan(nodeArray); // Replace nodes with copy. nodes = nodeArray; }
/// <summary> /// Add nodes using copy on write semantics. /// </summary> private void AddNodes(Dictionary <string, Node> nodesToAdd) { // Add all nodes at once to avoid copying entire array multiple times. // Create temporary nodes array. Node[] nodeArray = new Node[nodes.Length + nodesToAdd.Count]; int count = 0; // Add existing nodes. foreach (Node node in nodes) { nodeArray[count++] = node; } // Add new nodes foreach (Node node in nodesToAdd.Values) { if (Log.InfoEnabled()) { Log.Info("Add node " + node); } nodeArray[count++] = node; nodesMap[node.Name] = node; // Add node's aliases to global alias set. // Aliases are only used in tend thread, so synchronization is not necessary. foreach (Host alias in node.aliases) { aliases[alias] = node; } } hasPartitionScan = Cluster.SupportsPartitionScan(nodeArray); // Replace nodes with copy. nodes = nodeArray; }