From 678c92c50c6fb7aa9a093f0d74d4f92742abd5e8 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Mon, 15 Jun 2020 16:07:45 -0700 Subject: Reorganize media assignment to correctly place facade order optimization --- .../Bind/AssignMediaCommand.cs | 159 ++++++++++----------- 1 file changed, 74 insertions(+), 85 deletions(-) (limited to 'src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs') diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs index 1d677a70..b75956b4 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/AssignMediaCommand.cs @@ -35,18 +35,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind private bool FilesCompressed { get; } - public string CabinetNameTemplate { private get; set; } + private string CabinetNameTemplate { get; set; } /// /// Gets cabinets with their file rows. /// public Dictionary> FileFacadesByCabinetMedia { get; private set; } - /// - /// Get media rows. - /// - public Dictionary MediaRows { get; private set; } - /// /// Get uncompressed file rows. This will contain file rows of File elements that are marked with compression=no. /// This contains all the files when Package element is marked with compression=no @@ -55,17 +50,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind public void Execute() { - var filesByCabinetMedia = new Dictionary>(); - - var mediaRows = new Dictionary(); - - var uncompressedFiles = new List(); - - var mediaTable = this.Section.Tuples.OfType().ToList(); - var mediaTemplateTable = this.Section.Tuples.OfType().ToList(); + var mediaTuples = this.Section.Tuples.OfType().ToList(); + var mediaTemplateTuples = this.Section.Tuples.OfType().ToList(); - // If both tables are authored, it is an error. - if (mediaTemplateTable.Count > 0 && mediaTable.Count > 1) + // If both tuples are authored, it is an error. + if (mediaTemplateTuples.Count > 0 && mediaTuples.Count > 1) { throw new WixException(ErrorMessages.MediaTableCollision(null)); } @@ -78,34 +67,44 @@ namespace WixToolset.Core.WindowsInstaller.Bind Cabinet = "#MergeModule.CABinet", }); - filesByCabinetMedia.Add(mergeModuleMediaTuple, new List(this.FileFacades)); + this.FileFacadesByCabinetMedia = new Dictionary> + { + { mergeModuleMediaTuple, this.FileFacades } + }; + + this.UncompressedFileFacades = Array.Empty(); } - else if (mediaTemplateTable.Count == 0) + else if (mediaTemplateTuples.Count == 0) { - this.ManuallyAssignFiles(mediaTable, this.FileFacades, filesByCabinetMedia, mediaRows, uncompressedFiles); + var filesByCabinetMedia = new Dictionary>(); + + var uncompressedFiles = new List(); + + this.ManuallyAssignFiles(mediaTuples, filesByCabinetMedia, uncompressedFiles); + + this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable)kvp.Value); + + this.UncompressedFileFacades = uncompressedFiles; } else { - this.AutoAssignFiles(mediaTable, filesByCabinetMedia, mediaRows, uncompressedFiles); - } + var filesByCabinetMedia = new Dictionary>(); - this.FileFacadesByCabinetMedia = new Dictionary>(); + var uncompressedFiles = new List(); - foreach (var mediaRowWithFiles in filesByCabinetMedia) - { - this.FileFacadesByCabinetMedia.Add(mediaRowWithFiles.Key, mediaRowWithFiles.Value); - } + this.AutoAssignFiles(mediaTuples, filesByCabinetMedia, uncompressedFiles); - this.MediaRows = mediaRows; + this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable)kvp.Value); - this.UncompressedFileFacades = uncompressedFiles; + this.UncompressedFileFacades = uncompressedFiles; + } } /// /// Assign files to cabinets based on MediaTemplate authoring. /// /// FileRowCollection - private void AutoAssignFiles(List mediaTable, Dictionary> filesByCabinetMedia, Dictionary mediaRows, List uncompressedFiles) + private void AutoAssignFiles(List mediaTable, Dictionary> filesByCabinetMedia, List uncompressedFiles) { const int MaxCabIndex = 999; @@ -158,6 +157,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind throw new WixException(ErrorMessages.MaximumUncompressedMediaSizeTooLarge(null, maxPreCabSizeInMB)); } + var mediaTuplesByDiskId = new Dictionary(); + foreach (var facade in this.FileFacades) { // When building a product, if the current file is not to be compressed or if @@ -171,44 +172,38 @@ namespace WixToolset.Core.WindowsInstaller.Bind if (currentCabIndex == MaxCabIndex) { // Associate current file with last cab (irrespective of the size) and cab index is not incremented anymore. - var cabinetFiles = filesByCabinetMedia[currentMediaRow]; - facade.DiskId = currentCabIndex; - cabinetFiles.Add(facade); - continue; - } - - // Update current cab size. - currentPreCabSize += (ulong)facade.FileSize; - - if (currentPreCabSize > maxPreCabSizeInBytes) - { - // Overflow due to current file - currentMediaRow = this.AddMediaRow(mediaTemplateRow, ++currentCabIndex); - mediaRows.Add(currentMediaRow.DiskId, currentMediaRow); - filesByCabinetMedia.Add(currentMediaRow, new List()); - - var cabinetFileRows = filesByCabinetMedia[currentMediaRow]; - facade.DiskId = currentCabIndex; - cabinetFileRows.Add(facade); - // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize - currentPreCabSize = (ulong)facade.FileSize; } else { - // File fits in the current cab. - if (currentMediaRow == null) + // Update current cab size. + currentPreCabSize += (ulong)facade.FileSize; + + // Overflow due to current file + if (currentPreCabSize > maxPreCabSizeInBytes) { - // Create new cab and MediaRow - currentMediaRow = this.AddMediaRow(mediaTemplateRow, ++currentCabIndex); - mediaRows.Add(currentMediaRow.DiskId, currentMediaRow); + currentMediaRow = this.AddMediaTuple(mediaTemplateRow, ++currentCabIndex); + mediaTuplesByDiskId.Add(currentMediaRow.DiskId, currentMediaRow); filesByCabinetMedia.Add(currentMediaRow, new List()); - } - // Associate current file with current cab. - var cabinetFiles = filesByCabinetMedia[currentMediaRow]; - facade.DiskId = currentCabIndex; - cabinetFiles.Add(facade); + // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize + currentPreCabSize = (ulong)facade.FileSize; + } + else // file fits in the current cab. + { + if (currentMediaRow == null) + { + // Create new cab and MediaRow + currentMediaRow = this.AddMediaTuple(mediaTemplateRow, ++currentCabIndex); + mediaTuplesByDiskId.Add(currentMediaRow.DiskId, currentMediaRow); + filesByCabinetMedia.Add(currentMediaRow, new List()); + } + } } + + // Associate current file with current cab. + var cabinetFiles = filesByCabinetMedia[currentMediaRow]; + facade.DiskId = currentCabIndex; + cabinetFiles.Add(facade); } // If there are uncompressed files and no MediaRow, create a default one. @@ -219,51 +214,45 @@ namespace WixToolset.Core.WindowsInstaller.Bind DiskId = 1, }); - mediaRows.Add(1, defaultMediaRow); + mediaTuplesByDiskId.Add(1, defaultMediaRow); } } /// /// Assign files to cabinets based on Media authoring. /// - /// - /// - private void ManuallyAssignFiles(List mediaTable, IEnumerable fileFacades, Dictionary> filesByCabinetMedia, Dictionary mediaRows, List uncompressedFiles) + private void ManuallyAssignFiles(List mediaTuples, Dictionary> filesByCabinetMedia, List uncompressedFiles) { - if (mediaTable.Any()) + var mediaTuplesByDiskId = new Dictionary(); + + if (mediaTuples.Any()) { - var cabinetMediaRows = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var mediaRow in mediaTable) + var cabinetMediaTuples = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var mediaTuple in mediaTuples) { // If the Media row has a cabinet, make sure it is unique across all Media rows. - if (!String.IsNullOrEmpty(mediaRow.Cabinet)) + if (!String.IsNullOrEmpty(mediaTuple.Cabinet)) { - if (cabinetMediaRows.TryGetValue(mediaRow.Cabinet, out var existingRow)) + if (cabinetMediaTuples.TryGetValue(mediaTuple.Cabinet, out var existingRow)) { - this.Messaging.Write(ErrorMessages.DuplicateCabinetName(mediaRow.SourceLineNumbers, mediaRow.Cabinet)); + this.Messaging.Write(ErrorMessages.DuplicateCabinetName(mediaTuple.SourceLineNumbers, mediaTuple.Cabinet)); this.Messaging.Write(ErrorMessages.DuplicateCabinetName2(existingRow.SourceLineNumbers, existingRow.Cabinet)); } else { - cabinetMediaRows.Add(mediaRow.Cabinet, mediaRow); + cabinetMediaTuples.Add(mediaTuple.Cabinet, mediaTuple); } - } - mediaRows.Add(mediaRow.DiskId, mediaRow); - } - } + filesByCabinetMedia.Add(mediaTuple, new List()); + } - foreach (var mediaRow in mediaRows.Values) - { - if (null != mediaRow.Cabinet) - { - filesByCabinetMedia.Add(mediaRow, new List()); + mediaTuplesByDiskId.Add(mediaTuple.DiskId, mediaTuple); } } - foreach (var facade in fileFacades) + foreach (var facade in this.FileFacades) { - if (!mediaRows.TryGetValue(facade.DiskId, out var mediaRow)) + if (!mediaTuplesByDiskId.TryGetValue(facade.DiskId, out var mediaTuple)) { this.Messaging.Write(ErrorMessages.MissingMedia(facade.SourceLineNumber, facade.DiskId)); continue; @@ -279,7 +268,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind } else // file is marked compressed. { - if (filesByCabinetMedia.TryGetValue(mediaRow, out var cabinetFiles)) + if (filesByCabinetMedia.TryGetValue(mediaTuple, out var cabinetFiles)) { cabinetFiles.Add(facade); } @@ -292,12 +281,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind } /// - /// Adds a row to the media table with cab name template filled in. + /// Adds a tuple to the section with cab name template filled in. /// /// /// /// - private MediaTuple AddMediaRow(WixMediaTemplateTuple mediaTemplateTuple, int cabIndex) + private MediaTuple AddMediaTuple(WixMediaTemplateTuple mediaTemplateTuple, int cabIndex) { return this.Section.AddTuple(new MediaTuple(mediaTemplateTuple.SourceLineNumbers, new Identifier(AccessModifier.Private, cabIndex)) { -- cgit v1.2.3-55-g6feb