public void UpdateDestinationTree() { _sourceToDestinationMap.Clear(); if (null == SourceTree || HasConflicts) { DestinationTree = null; } else { Dictionary <string, FileNode> sourceFileNameMap = FileNameMap(SourceTree); List <string> fileNames = new List <string>(); foreach (string name in sourceFileNameMap.Keys) { ListUtils.SortedInsert(fileNames, name); } AlphaFolderCollection alphaFolders = MaxDirectories > 0 ? AlphaFolderCollection.GetAlphaFolders(fileNames, MaxDirectories) : null; DirectoryNode destinationTree = new DirectoryNode(SourceTree.Name); foreach (string fileName in fileNames) { string folderName = alphaFolders?.GetFolderNameForFile(fileName); DirectoryNode destinationDir = null != folderName?destinationTree.FindDirectory(folderName) : destinationTree; if (null == destinationDir) { destinationDir = (DirectoryNode)destinationTree.AddChildNode(new DirectoryNode(folderName, destinationTree)); } FileNode destinationFile = (FileNode)destinationDir.AddChildNode(new FileNode(fileName, destinationDir)); _sourceToDestinationMap.Add(sourceFileNameMap[fileName], destinationFile); } DestinationTree = destinationTree; } }
public static AlphaFolderCollection GetAlphaFolders(IEnumerable <string> fileNames, uint maxFolders) { if (null == fileNames) { throw new ArgumentNullException(nameof(fileNames)); } if (maxFolders < 1) { throw new ArgumentOutOfRangeException(nameof(maxFolders)); } AlphaFolderCollection collection = new AlphaFolderCollection(); foreach (string fileName in fileNames) { char firstChar = fileName[0]; string subDir = char.IsLetter(firstChar) ? firstChar.ToString().ToUpper() : AlphaFolder.NumericAlphaFolder; if (!collection.HasFolderForFile(fileName)) { collection.AddFolder(subDir); } collection.AddFile(fileName); } while (collection.Count > maxFolders) { int minPairIndexA = 0; int minPairIndexB = 0; int minPairCount = int.MaxValue; int minIndex = 0; int minCount = int.MaxValue; for (int i = 0; i < collection.Count; i++) { int count = collection.Get(i).Files.Count; // Find absolute smallest if (count <= minCount) { minIndex = i; minCount = count; } // Find smallest pair if (i + 1 < collection.Count) { int neighborCount = collection.Get(i + 1).Files.Count; if (count + neighborCount <= minPairCount) { minPairIndexA = i; minPairIndexB = i + 1; minPairCount = count + neighborCount; } } } // Find smallest neighbor to minIndex int minNeighborIndex = minIndex; if (minNeighborIndex == 0) { minNeighborIndex++; } else if (minNeighborIndex == collection.Count - 1) { minNeighborIndex--; } else { int minNeighborLeftCount = collection.Get(minIndex - 1).Files.Count; int minNeighborRightCount = collection.Get(minIndex + 1).Files.Count; if (minNeighborLeftCount <= minNeighborRightCount) { minNeighborIndex--; } else { minNeighborIndex++; } } int minNeighborCount = collection.Get(minNeighborIndex).Files.Count; if (minPairCount < minCount + minNeighborCount) { collection.CombineFolders(minPairIndexA, minPairIndexB); } else { collection.CombineFolders(minIndex, minNeighborIndex); } } return(collection); }