/// <summary>Pick up replica node set for deleting replica as over-replicated.</summary> /// <remarks> /// Pick up replica node set for deleting replica as over-replicated. /// First set contains replica nodes on rack with more than one /// replica while second set contains remaining replica nodes. /// If first is not empty, divide first set into two subsets: /// moreThanOne contains nodes on nodegroup with more than one replica /// exactlyOne contains the remaining nodes in first set /// then pickup priSet if not empty. /// If first is empty, then pick second. /// </remarks> protected internal override ICollection <DatanodeStorageInfo> PickupReplicaSet(ICollection <DatanodeStorageInfo> first, ICollection <DatanodeStorageInfo> second) { // If no replica within same rack, return directly. if (first.IsEmpty()) { return(second); } // Split data nodes in the first set into two sets, // moreThanOne contains nodes on nodegroup with more than one replica // exactlyOne contains the remaining nodes IDictionary <string, IList <DatanodeStorageInfo> > nodeGroupMap = new Dictionary <string , IList <DatanodeStorageInfo> >(); foreach (DatanodeStorageInfo storage in first) { string nodeGroupName = NetworkTopology.GetLastHalf(storage.GetDatanodeDescriptor( ).GetNetworkLocation()); IList <DatanodeStorageInfo> storageList = nodeGroupMap[nodeGroupName]; if (storageList == null) { storageList = new AList <DatanodeStorageInfo>(); nodeGroupMap[nodeGroupName] = storageList; } storageList.AddItem(storage); } IList <DatanodeStorageInfo> moreThanOne = new AList <DatanodeStorageInfo>(); IList <DatanodeStorageInfo> exactlyOne = new AList <DatanodeStorageInfo>(); // split nodes into two sets foreach (IList <DatanodeStorageInfo> datanodeList in nodeGroupMap.Values) { if (datanodeList.Count == 1) { // exactlyOne contains nodes on nodegroup with exactly one replica exactlyOne.AddItem(datanodeList[0]); } else { // moreThanOne contains nodes on nodegroup with more than one replica Sharpen.Collections.AddAll(moreThanOne, datanodeList); } } return(moreThanOne.IsEmpty() ? exactlyOne : moreThanOne); }
/// <summary>Scan the targets list: all targets should be on different NodeGroups.</summary> /// <remarks> /// Scan the targets list: all targets should be on different NodeGroups. /// Return false if two targets are found on the same NodeGroup. /// </remarks> private static bool CheckTargetsOnDifferentNodeGroup(DatanodeStorageInfo[] targets ) { if (targets.Length == 0) { return(true); } ICollection <string> targetSet = new HashSet <string>(); foreach (DatanodeStorageInfo storage in targets) { DatanodeDescriptor node = storage.GetDatanodeDescriptor(); string nodeGroup = NetworkTopology.GetLastHalf(node.GetNetworkLocation()); if (targetSet.Contains(nodeGroup)) { return(false); } else { targetSet.AddItem(nodeGroup); } } return(true); }