/// <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;
        }
Пример #3
0
        /// <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);
        }