/// <summary> /// Computes the list of volume containers to be migrated together /// </summary> /// <returns>list of related volume container(s) which needs to be migrated together</returns> private List<List<MigrationDataContainer>> ComputedRelatedVolumeContainers() { var dcDict = new Dictionary<string, DataContainerInfo>(); foreach (var virtualDiskGroup in this.VolumeGroups) { List<string> diskIDList = virtualDiskGroup.VirtualDiskList.ToList(); string vDGIdentity = Guid.NewGuid().ToString(); foreach (string virtualDiskId in diskIDList) { VirtualDisk virtualDisk = this.Volumes.FirstOrDefault(volume => (volume.InstanceId == virtualDiskId)); MigrationDataContainer dataContainer = this.CloudConfigurations.FirstOrDefault( volumeContainer => (volumeContainer.InstanceId == virtualDisk.DataContainerId)); if (null != dataContainer) { if (!dcDict.ContainsKey(dataContainer.InstanceId)) { DataContainerInfo newDc = new DataContainerInfo() { DcInfo = dataContainer, VirtualDiskGroups = new List<string>() {vDGIdentity}, Visited = false }; dcDict.Add(dataContainer.InstanceId, newDc); } else if (!dcDict[dataContainer.InstanceId].VirtualDiskGroups.Contains(vDGIdentity)) { dcDict[dataContainer.InstanceId].VirtualDiskGroups.Add(vDGIdentity); } } else { throw new MissingMemberException( string.Format(Resources.MigrationVolumeToVolumeContainerMapNotFound, virtualDisk.DataContainerId, virtualDisk.InstanceId)); } } } foreach (var dataContainer in this.CloudConfigurations) { if (!dcDict.Keys.Contains(dataContainer.InstanceId)) { dcDict.Add(dataContainer.InstanceId, new DataContainerInfo() { DcInfo = dataContainer, VirtualDiskGroups = new List<string>(), Visited = false }); } } DataContainerInfo[] dcArray = dcDict.Values.ToArray(); // create an adjacency matrix of DCs bool[,] dcGraph = new bool[dcDict.Count, dcDict.Count]; for (int row = 0; row < dcDict.Count; row++) { for (int col = 0; col < dcDict.Count; col++) { dcGraph[row, col] = false; } } for (int row = 0; row < dcArray.Count(); row++) { DataContainerInfo currDc = dcArray[row]; foreach (string groupInstanceID in currDc.VirtualDiskGroups) { for (int col = 0; col < dcArray.Count(); col++) { DataContainerInfo otherDc = dcArray[col]; if (!currDc.DcInfo.InstanceId.Equals(otherDc.DcInfo.InstanceId) && // we're looking at the same vertex !(dcGraph[row, col] && dcGraph[col, row])) // or the vertices are already known neighbours { if (otherDc.VirtualDiskGroups.Contains(groupInstanceID)) { dcGraph[row, col] = true; dcGraph[col, row] = true; } } } } } // evaluate DCs connected by policies List<List<MigrationDataContainer>> connectedDCs = new List<List<MigrationDataContainer>>(); for (int index = 0; index < dcArray.Count(); index++) { if (dcArray[index].Visited == false) { connectedDCs.Add(RunDFS(dcGraph, dcArray, index, new List<MigrationDataContainer>())); } } return connectedDCs; }
/// <summary> /// DFS algorithm to traverse through the volume container graph and returns dependent container list /// </summary> /// <param name="dcGraph">data container graph</param> /// <param name="dcArray">list of data containers</param> /// <param name="startingNode">starting node for traversal</param> /// <param name="traversedNodes">list of nodes already discovered from previous iteration (to start with this pass as empty)</param> /// <returns>dependent data container list</returns> private List<MigrationDataContainer> RunDFS(bool[,] dcGraph, DataContainerInfo[] dcArray, int startingNode, List<MigrationDataContainer> traversedNodes) { traversedNodes.Add(dcArray[startingNode].DcInfo); dcArray[startingNode].Visited = true; for (int index = 0; index < dcArray.Count(); index++) { if ((dcGraph[startingNode, index] == true) && (dcArray[index].Visited == false)) { RunDFS(dcGraph, dcArray, index, traversedNodes); } } return traversedNodes; }
/// <summary> /// Computes the list of volume containers to be migrated together /// </summary> /// <returns>list of related volume container(s) which needs to be migrated together</returns> private List <List <MigrationDataContainer> > ComputedRelatedVolumeContainers() { var dcDict = new Dictionary <string, DataContainerInfo>(); foreach (var virtualDiskGroup in this.VolumeGroups) { List <string> diskIDList = virtualDiskGroup.VirtualDiskList.ToList(); string vDGIdentity = Guid.NewGuid().ToString(); foreach (string virtualDiskId in diskIDList) { VirtualDisk virtualDisk = this.Volumes.FirstOrDefault(volume => (volume.InstanceId == virtualDiskId)); MigrationDataContainer dataContainer = this.CloudConfigurations.FirstOrDefault( volumeContainer => (volumeContainer.InstanceId == virtualDisk.DataContainerId)); if (null != dataContainer) { if (!dcDict.ContainsKey(dataContainer.InstanceId)) { DataContainerInfo newDc = new DataContainerInfo() { DcInfo = dataContainer, VirtualDiskGroups = new List <string>() { vDGIdentity }, Visited = false }; dcDict.Add(dataContainer.InstanceId, newDc); } else if (!dcDict[dataContainer.InstanceId].VirtualDiskGroups.Contains(vDGIdentity)) { dcDict[dataContainer.InstanceId].VirtualDiskGroups.Add(vDGIdentity); } } else { throw new MissingMemberException( string.Format(Resources.MigrationVolumeToVolumeContainerMapNotFound, virtualDisk.DataContainerId, virtualDisk.InstanceId)); } } } foreach (var dataContainer in this.CloudConfigurations) { if (!dcDict.Keys.Contains(dataContainer.InstanceId)) { dcDict.Add(dataContainer.InstanceId, new DataContainerInfo() { DcInfo = dataContainer, VirtualDiskGroups = new List <string>(), Visited = false }); } } DataContainerInfo[] dcArray = dcDict.Values.ToArray(); // create an adjacency matrix of DCs bool[,] dcGraph = new bool[dcDict.Count, dcDict.Count]; for (int row = 0; row < dcDict.Count; row++) { for (int col = 0; col < dcDict.Count; col++) { dcGraph[row, col] = false; } } for (int row = 0; row < dcArray.Count(); row++) { DataContainerInfo currDc = dcArray[row]; foreach (string groupInstanceID in currDc.VirtualDiskGroups) { for (int col = 0; col < dcArray.Count(); col++) { DataContainerInfo otherDc = dcArray[col]; if (!currDc.DcInfo.InstanceId.Equals(otherDc.DcInfo.InstanceId) && // we're looking at the same vertex !(dcGraph[row, col] && dcGraph[col, row])) // or the vertices are already known neighbours { if (otherDc.VirtualDiskGroups.Contains(groupInstanceID)) { dcGraph[row, col] = true; dcGraph[col, row] = true; } } } } } // evaluate DCs connected by policies List <List <MigrationDataContainer> > connectedDCs = new List <List <MigrationDataContainer> >(); for (int index = 0; index < dcArray.Count(); index++) { if (dcArray[index].Visited == false) { connectedDCs.Add(RunDFS(dcGraph, dcArray, index, new List <MigrationDataContainer>())); } } return(connectedDCs); }