diff options
| author | Rob Mensching <rob@firegiant.com> | 2020-06-15 16:07:45 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2020-06-16 12:15:13 -0700 |
| commit | 678c92c50c6fb7aa9a093f0d74d4f92742abd5e8 (patch) | |
| tree | ef4d007b74e56734a5258e2235988fbc0ef6996f /src/WixToolset.Core.WindowsInstaller | |
| parent | 3fb3475b278803576badecfbe8015760de2e7414 (diff) | |
| download | wix-678c92c50c6fb7aa9a093f0d74d4f92742abd5e8.tar.gz wix-678c92c50c6fb7aa9a093f0d74d4f92742abd5e8.tar.bz2 wix-678c92c50c6fb7aa9a093f0d74d4f92742abd5e8.zip | |
Reorganize media assignment to correctly place facade order optimization
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller')
6 files changed, 135 insertions, 124 deletions
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,7 +35,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 35 | 35 | ||
| 36 | private bool FilesCompressed { get; } | 36 | private bool FilesCompressed { get; } |
| 37 | 37 | ||
| 38 | public string CabinetNameTemplate { private get; set; } | 38 | private string CabinetNameTemplate { get; set; } |
| 39 | 39 | ||
| 40 | /// <summary> | 40 | /// <summary> |
| 41 | /// Gets cabinets with their file rows. | 41 | /// Gets cabinets with their file rows. |
| @@ -43,11 +43,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 43 | public Dictionary<MediaTuple, IEnumerable<FileFacade>> FileFacadesByCabinetMedia { get; private set; } | 43 | public Dictionary<MediaTuple, IEnumerable<FileFacade>> FileFacadesByCabinetMedia { get; private set; } |
| 44 | 44 | ||
| 45 | /// <summary> | 45 | /// <summary> |
| 46 | /// Get media rows. | ||
| 47 | /// </summary> | ||
| 48 | public Dictionary<int, MediaTuple> MediaRows { get; private set; } | ||
| 49 | |||
| 50 | /// <summary> | ||
| 51 | /// Get uncompressed file rows. This will contain file rows of File elements that are marked with compression=no. | 46 | /// Get uncompressed file rows. This will contain file rows of File elements that are marked with compression=no. |
| 52 | /// This contains all the files when Package element is marked with compression=no | 47 | /// This contains all the files when Package element is marked with compression=no |
| 53 | /// </summary> | 48 | /// </summary> |
| @@ -55,17 +50,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 55 | 50 | ||
| 56 | public void Execute() | 51 | public void Execute() |
| 57 | { | 52 | { |
| 58 | var filesByCabinetMedia = new Dictionary<MediaTuple, List<FileFacade>>(); | 53 | var mediaTuples = this.Section.Tuples.OfType<MediaTuple>().ToList(); |
| 59 | 54 | var mediaTemplateTuples = this.Section.Tuples.OfType<WixMediaTemplateTuple>().ToList(); | |
| 60 | var mediaRows = new Dictionary<int, MediaTuple>(); | ||
| 61 | |||
| 62 | var uncompressedFiles = new List<FileFacade>(); | ||
| 63 | |||
| 64 | var mediaTable = this.Section.Tuples.OfType<MediaTuple>().ToList(); | ||
| 65 | var mediaTemplateTable = this.Section.Tuples.OfType<WixMediaTemplateTuple>().ToList(); | ||
| 66 | 55 | ||
| 67 | // If both tables are authored, it is an error. | 56 | // If both tuples are authored, it is an error. |
| 68 | if (mediaTemplateTable.Count > 0 && mediaTable.Count > 1) | 57 | if (mediaTemplateTuples.Count > 0 && mediaTuples.Count > 1) |
| 69 | { | 58 | { |
| 70 | throw new WixException(ErrorMessages.MediaTableCollision(null)); | 59 | throw new WixException(ErrorMessages.MediaTableCollision(null)); |
| 71 | } | 60 | } |
| @@ -78,34 +67,44 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 78 | Cabinet = "#MergeModule.CABinet", | 67 | Cabinet = "#MergeModule.CABinet", |
| 79 | }); | 68 | }); |
| 80 | 69 | ||
| 81 | filesByCabinetMedia.Add(mergeModuleMediaTuple, new List<FileFacade>(this.FileFacades)); | 70 | this.FileFacadesByCabinetMedia = new Dictionary<MediaTuple, IEnumerable<FileFacade>> |
| 71 | { | ||
| 72 | { mergeModuleMediaTuple, this.FileFacades } | ||
| 73 | }; | ||
| 74 | |||
| 75 | this.UncompressedFileFacades = Array.Empty<FileFacade>(); | ||
| 82 | } | 76 | } |
| 83 | else if (mediaTemplateTable.Count == 0) | 77 | else if (mediaTemplateTuples.Count == 0) |
| 84 | { | 78 | { |
| 85 | this.ManuallyAssignFiles(mediaTable, this.FileFacades, filesByCabinetMedia, mediaRows, uncompressedFiles); | 79 | var filesByCabinetMedia = new Dictionary<MediaTuple, List<FileFacade>>(); |
| 80 | |||
| 81 | var uncompressedFiles = new List<FileFacade>(); | ||
| 82 | |||
| 83 | this.ManuallyAssignFiles(mediaTuples, filesByCabinetMedia, uncompressedFiles); | ||
| 84 | |||
| 85 | this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable<FileFacade>)kvp.Value); | ||
| 86 | |||
| 87 | this.UncompressedFileFacades = uncompressedFiles; | ||
| 86 | } | 88 | } |
| 87 | else | 89 | else |
| 88 | { | 90 | { |
| 89 | this.AutoAssignFiles(mediaTable, filesByCabinetMedia, mediaRows, uncompressedFiles); | 91 | var filesByCabinetMedia = new Dictionary<MediaTuple, List<FileFacade>>(); |
| 90 | } | ||
| 91 | 92 | ||
| 92 | this.FileFacadesByCabinetMedia = new Dictionary<MediaTuple, IEnumerable<FileFacade>>(); | 93 | var uncompressedFiles = new List<FileFacade>(); |
| 93 | 94 | ||
| 94 | foreach (var mediaRowWithFiles in filesByCabinetMedia) | 95 | this.AutoAssignFiles(mediaTuples, filesByCabinetMedia, uncompressedFiles); |
| 95 | { | ||
| 96 | this.FileFacadesByCabinetMedia.Add(mediaRowWithFiles.Key, mediaRowWithFiles.Value); | ||
| 97 | } | ||
| 98 | 96 | ||
| 99 | this.MediaRows = mediaRows; | 97 | this.FileFacadesByCabinetMedia = filesByCabinetMedia.ToDictionary(kvp => kvp.Key, kvp => (IEnumerable<FileFacade>)kvp.Value); |
| 100 | 98 | ||
| 101 | this.UncompressedFileFacades = uncompressedFiles; | 99 | this.UncompressedFileFacades = uncompressedFiles; |
| 100 | } | ||
| 102 | } | 101 | } |
| 103 | 102 | ||
| 104 | /// <summary> | 103 | /// <summary> |
| 105 | /// Assign files to cabinets based on MediaTemplate authoring. | 104 | /// Assign files to cabinets based on MediaTemplate authoring. |
| 106 | /// </summary> | 105 | /// </summary> |
| 107 | /// <param name="fileFacades">FileRowCollection</param> | 106 | /// <param name="fileFacades">FileRowCollection</param> |
| 108 | private void AutoAssignFiles(List<MediaTuple> mediaTable, Dictionary<MediaTuple, List<FileFacade>> filesByCabinetMedia, Dictionary<int, MediaTuple> mediaRows, List<FileFacade> uncompressedFiles) | 107 | private void AutoAssignFiles(List<MediaTuple> mediaTable, Dictionary<MediaTuple, List<FileFacade>> filesByCabinetMedia, List<FileFacade> uncompressedFiles) |
| 109 | { | 108 | { |
| 110 | const int MaxCabIndex = 999; | 109 | const int MaxCabIndex = 999; |
| 111 | 110 | ||
| @@ -158,6 +157,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 158 | throw new WixException(ErrorMessages.MaximumUncompressedMediaSizeTooLarge(null, maxPreCabSizeInMB)); | 157 | throw new WixException(ErrorMessages.MaximumUncompressedMediaSizeTooLarge(null, maxPreCabSizeInMB)); |
| 159 | } | 158 | } |
| 160 | 159 | ||
| 160 | var mediaTuplesByDiskId = new Dictionary<int, MediaTuple>(); | ||
| 161 | |||
| 161 | foreach (var facade in this.FileFacades) | 162 | foreach (var facade in this.FileFacades) |
| 162 | { | 163 | { |
| 163 | // When building a product, if the current file is not to be compressed or if | 164 | // When building a product, if the current file is not to be compressed or if |
| @@ -171,44 +172,38 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 171 | if (currentCabIndex == MaxCabIndex) | 172 | if (currentCabIndex == MaxCabIndex) |
| 172 | { | 173 | { |
| 173 | // Associate current file with last cab (irrespective of the size) and cab index is not incremented anymore. | 174 | // Associate current file with last cab (irrespective of the size) and cab index is not incremented anymore. |
| 174 | var cabinetFiles = filesByCabinetMedia[currentMediaRow]; | ||
| 175 | facade.DiskId = currentCabIndex; | ||
| 176 | cabinetFiles.Add(facade); | ||
| 177 | continue; | ||
| 178 | } | ||
| 179 | |||
| 180 | // Update current cab size. | ||
| 181 | currentPreCabSize += (ulong)facade.FileSize; | ||
| 182 | |||
| 183 | if (currentPreCabSize > maxPreCabSizeInBytes) | ||
| 184 | { | ||
| 185 | // Overflow due to current file | ||
| 186 | currentMediaRow = this.AddMediaRow(mediaTemplateRow, ++currentCabIndex); | ||
| 187 | mediaRows.Add(currentMediaRow.DiskId, currentMediaRow); | ||
| 188 | filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>()); | ||
| 189 | |||
| 190 | var cabinetFileRows = filesByCabinetMedia[currentMediaRow]; | ||
| 191 | facade.DiskId = currentCabIndex; | ||
| 192 | cabinetFileRows.Add(facade); | ||
| 193 | // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize | ||
| 194 | currentPreCabSize = (ulong)facade.FileSize; | ||
| 195 | } | 175 | } |
| 196 | else | 176 | else |
| 197 | { | 177 | { |
| 198 | // File fits in the current cab. | 178 | // Update current cab size. |
| 199 | if (currentMediaRow == null) | 179 | currentPreCabSize += (ulong)facade.FileSize; |
| 180 | |||
| 181 | // Overflow due to current file | ||
| 182 | if (currentPreCabSize > maxPreCabSizeInBytes) | ||
| 200 | { | 183 | { |
| 201 | // Create new cab and MediaRow | 184 | currentMediaRow = this.AddMediaTuple(mediaTemplateRow, ++currentCabIndex); |
| 202 | currentMediaRow = this.AddMediaRow(mediaTemplateRow, ++currentCabIndex); | 185 | mediaTuplesByDiskId.Add(currentMediaRow.DiskId, currentMediaRow); |
| 203 | mediaRows.Add(currentMediaRow.DiskId, currentMediaRow); | ||
| 204 | filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>()); | 186 | filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>()); |
| 205 | } | ||
| 206 | 187 | ||
| 207 | // Associate current file with current cab. | 188 | // Now files larger than MaxUncompressedMediaSize will be the only file in its cabinet so as to respect MaxUncompressedMediaSize |
| 208 | var cabinetFiles = filesByCabinetMedia[currentMediaRow]; | 189 | currentPreCabSize = (ulong)facade.FileSize; |
| 209 | facade.DiskId = currentCabIndex; | 190 | } |
| 210 | cabinetFiles.Add(facade); | 191 | else // file fits in the current cab. |
| 192 | { | ||
| 193 | if (currentMediaRow == null) | ||
| 194 | { | ||
| 195 | // Create new cab and MediaRow | ||
| 196 | currentMediaRow = this.AddMediaTuple(mediaTemplateRow, ++currentCabIndex); | ||
| 197 | mediaTuplesByDiskId.Add(currentMediaRow.DiskId, currentMediaRow); | ||
| 198 | filesByCabinetMedia.Add(currentMediaRow, new List<FileFacade>()); | ||
| 199 | } | ||
| 200 | } | ||
| 211 | } | 201 | } |
| 202 | |||
| 203 | // Associate current file with current cab. | ||
| 204 | var cabinetFiles = filesByCabinetMedia[currentMediaRow]; | ||
| 205 | facade.DiskId = currentCabIndex; | ||
| 206 | cabinetFiles.Add(facade); | ||
| 212 | } | 207 | } |
| 213 | 208 | ||
| 214 | // If there are uncompressed files and no MediaRow, create a default one. | 209 | // If there are uncompressed files and no MediaRow, create a default one. |
| @@ -219,51 +214,45 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 219 | DiskId = 1, | 214 | DiskId = 1, |
| 220 | }); | 215 | }); |
| 221 | 216 | ||
| 222 | mediaRows.Add(1, defaultMediaRow); | 217 | mediaTuplesByDiskId.Add(1, defaultMediaRow); |
| 223 | } | 218 | } |
| 224 | } | 219 | } |
| 225 | 220 | ||
| 226 | /// <summary> | 221 | /// <summary> |
| 227 | /// Assign files to cabinets based on Media authoring. | 222 | /// Assign files to cabinets based on Media authoring. |
| 228 | /// </summary> | 223 | /// </summary> |
| 229 | /// <param name="mediaTable"></param> | 224 | private void ManuallyAssignFiles(List<MediaTuple> mediaTuples, Dictionary<MediaTuple, List<FileFacade>> filesByCabinetMedia, List<FileFacade> uncompressedFiles) |
| 230 | /// <param name="fileFacades"></param> | ||
| 231 | private void ManuallyAssignFiles(List<MediaTuple> mediaTable, IEnumerable<FileFacade> fileFacades, Dictionary<MediaTuple, List<FileFacade>> filesByCabinetMedia, Dictionary<int, MediaTuple> mediaRows, List<FileFacade> uncompressedFiles) | ||
| 232 | { | 225 | { |
| 233 | if (mediaTable.Any()) | 226 | var mediaTuplesByDiskId = new Dictionary<int, MediaTuple>(); |
| 227 | |||
| 228 | if (mediaTuples.Any()) | ||
| 234 | { | 229 | { |
| 235 | var cabinetMediaRows = new Dictionary<string, MediaTuple>(StringComparer.OrdinalIgnoreCase); | 230 | var cabinetMediaTuples = new Dictionary<string, MediaTuple>(StringComparer.OrdinalIgnoreCase); |
| 236 | foreach (var mediaRow in mediaTable) | 231 | foreach (var mediaTuple in mediaTuples) |
| 237 | { | 232 | { |
| 238 | // If the Media row has a cabinet, make sure it is unique across all Media rows. | 233 | // If the Media row has a cabinet, make sure it is unique across all Media rows. |
| 239 | if (!String.IsNullOrEmpty(mediaRow.Cabinet)) | 234 | if (!String.IsNullOrEmpty(mediaTuple.Cabinet)) |
| 240 | { | 235 | { |
| 241 | if (cabinetMediaRows.TryGetValue(mediaRow.Cabinet, out var existingRow)) | 236 | if (cabinetMediaTuples.TryGetValue(mediaTuple.Cabinet, out var existingRow)) |
| 242 | { | 237 | { |
| 243 | this.Messaging.Write(ErrorMessages.DuplicateCabinetName(mediaRow.SourceLineNumbers, mediaRow.Cabinet)); | 238 | this.Messaging.Write(ErrorMessages.DuplicateCabinetName(mediaTuple.SourceLineNumbers, mediaTuple.Cabinet)); |
| 244 | this.Messaging.Write(ErrorMessages.DuplicateCabinetName2(existingRow.SourceLineNumbers, existingRow.Cabinet)); | 239 | this.Messaging.Write(ErrorMessages.DuplicateCabinetName2(existingRow.SourceLineNumbers, existingRow.Cabinet)); |
| 245 | } | 240 | } |
| 246 | else | 241 | else |
| 247 | { | 242 | { |
| 248 | cabinetMediaRows.Add(mediaRow.Cabinet, mediaRow); | 243 | cabinetMediaTuples.Add(mediaTuple.Cabinet, mediaTuple); |
| 249 | } | 244 | } |
| 250 | } | ||
| 251 | 245 | ||
| 252 | mediaRows.Add(mediaRow.DiskId, mediaRow); | 246 | filesByCabinetMedia.Add(mediaTuple, new List<FileFacade>()); |
| 253 | } | 247 | } |
| 254 | } | ||
| 255 | 248 | ||
| 256 | foreach (var mediaRow in mediaRows.Values) | 249 | mediaTuplesByDiskId.Add(mediaTuple.DiskId, mediaTuple); |
| 257 | { | ||
| 258 | if (null != mediaRow.Cabinet) | ||
| 259 | { | ||
| 260 | filesByCabinetMedia.Add(mediaRow, new List<FileFacade>()); | ||
| 261 | } | 250 | } |
| 262 | } | 251 | } |
| 263 | 252 | ||
| 264 | foreach (var facade in fileFacades) | 253 | foreach (var facade in this.FileFacades) |
| 265 | { | 254 | { |
| 266 | if (!mediaRows.TryGetValue(facade.DiskId, out var mediaRow)) | 255 | if (!mediaTuplesByDiskId.TryGetValue(facade.DiskId, out var mediaTuple)) |
| 267 | { | 256 | { |
| 268 | this.Messaging.Write(ErrorMessages.MissingMedia(facade.SourceLineNumber, facade.DiskId)); | 257 | this.Messaging.Write(ErrorMessages.MissingMedia(facade.SourceLineNumber, facade.DiskId)); |
| 269 | continue; | 258 | continue; |
| @@ -279,7 +268,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 279 | } | 268 | } |
| 280 | else // file is marked compressed. | 269 | else // file is marked compressed. |
| 281 | { | 270 | { |
| 282 | if (filesByCabinetMedia.TryGetValue(mediaRow, out var cabinetFiles)) | 271 | if (filesByCabinetMedia.TryGetValue(mediaTuple, out var cabinetFiles)) |
| 283 | { | 272 | { |
| 284 | cabinetFiles.Add(facade); | 273 | cabinetFiles.Add(facade); |
| 285 | } | 274 | } |
| @@ -292,12 +281,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 292 | } | 281 | } |
| 293 | 282 | ||
| 294 | /// <summary> | 283 | /// <summary> |
| 295 | /// Adds a row to the media table with cab name template filled in. | 284 | /// Adds a tuple to the section with cab name template filled in. |
| 296 | /// </summary> | 285 | /// </summary> |
| 297 | /// <param name="mediaTable"></param> | 286 | /// <param name="mediaTable"></param> |
| 298 | /// <param name="cabIndex"></param> | 287 | /// <param name="cabIndex"></param> |
| 299 | /// <returns></returns> | 288 | /// <returns></returns> |
| 300 | private MediaTuple AddMediaRow(WixMediaTemplateTuple mediaTemplateTuple, int cabIndex) | 289 | private MediaTuple AddMediaTuple(WixMediaTemplateTuple mediaTemplateTuple, int cabIndex) |
| 301 | { | 290 | { |
| 302 | return this.Section.AddTuple(new MediaTuple(mediaTemplateTuple.SourceLineNumbers, new Identifier(AccessModifier.Private, cabIndex)) | 291 | return this.Section.AddTuple(new MediaTuple(mediaTemplateTuple.SourceLineNumbers, new Identifier(AccessModifier.Private, cabIndex)) |
| 303 | { | 292 | { |
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs index 6c2968ec..da92be69 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs | |||
| @@ -281,19 +281,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 281 | command.Execute(); | 281 | command.Execute(); |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | // Assign files to media. | ||
| 285 | Dictionary<int, MediaTuple> assignedMediaRows; | ||
| 286 | Dictionary<MediaTuple, IEnumerable<FileFacade>> filesByCabinetMedia; | ||
| 287 | IEnumerable<FileFacade> uncompressedFiles; | ||
| 288 | { | ||
| 289 | var command = new AssignMediaCommand(section, this.Messaging, fileFacades, compressed); | ||
| 290 | command.Execute(); | ||
| 291 | |||
| 292 | assignedMediaRows = command.MediaRows; | ||
| 293 | filesByCabinetMedia = command.FileFacadesByCabinetMedia; | ||
| 294 | uncompressedFiles = command.UncompressedFileFacades; | ||
| 295 | } | ||
| 296 | |||
| 297 | // stop processing if an error previously occurred | 284 | // stop processing if an error previously occurred |
| 298 | if (this.Messaging.EncounteredError) | 285 | if (this.Messaging.EncounteredError) |
| 299 | { | 286 | { |
| @@ -366,10 +353,23 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 366 | command.Execute(); | 353 | command.Execute(); |
| 367 | } | 354 | } |
| 368 | 355 | ||
| 369 | // Update file sequence. | 356 | // Assign files to media and update file sequences. |
| 357 | Dictionary<MediaTuple, IEnumerable<FileFacade>> filesByCabinetMedia; | ||
| 358 | IEnumerable<FileFacade> uncompressedFiles; | ||
| 370 | { | 359 | { |
| 371 | var command = new UpdateMediaSequencesCommand(section, fileFacades); | 360 | var order = new OptimizeFileFacadesOrderCommand(fileFacades); |
| 372 | command.Execute(); | 361 | order.Execute(); |
| 362 | |||
| 363 | fileFacades = order.FileFacades; | ||
| 364 | |||
| 365 | var assign = new AssignMediaCommand(section, this.Messaging, fileFacades, compressed); | ||
| 366 | assign.Execute(); | ||
| 367 | |||
| 368 | filesByCabinetMedia = assign.FileFacadesByCabinetMedia; | ||
| 369 | uncompressedFiles = assign.UncompressedFileFacades; | ||
| 370 | |||
| 371 | var update = new UpdateMediaSequencesCommand(section, fileFacades); | ||
| 372 | update.Execute(); | ||
| 373 | } | 373 | } |
| 374 | 374 | ||
| 375 | // stop processing if an error previously occurred | 375 | // stop processing if an error previously occurred |
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs index 486ee67a..dce89f78 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs | |||
| @@ -7,7 +7,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 7 | using System.IO; | 7 | using System.IO; |
| 8 | using System.Linq; | 8 | using System.Linq; |
| 9 | using System.Threading; | 9 | using System.Threading; |
| 10 | using WixToolset.Core.Bind; | ||
| 11 | using WixToolset.Core.Native; | 10 | using WixToolset.Core.Native; |
| 12 | using WixToolset.Data; | 11 | using WixToolset.Data; |
| 13 | using WixToolset.Extensibility.Services; | 12 | using WixToolset.Extensibility.Services; |
| @@ -18,12 +17,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 18 | /// </summary> | 17 | /// </summary> |
| 19 | internal sealed class CabinetBuilder | 18 | internal sealed class CabinetBuilder |
| 20 | { | 19 | { |
| 21 | private Queue cabinetWorkItems; | 20 | private readonly object lockObject = new object(); |
| 22 | private object lockObject; | 21 | |
| 22 | private readonly Queue cabinetWorkItems; | ||
| 23 | private int threadCount; | 23 | private int threadCount; |
| 24 | 24 | ||
| 25 | // Address of Binder's callback function for Cabinet Splitting | 25 | // Address of Binder's callback function for Cabinet Splitting |
| 26 | private IntPtr newCabNamesCallBackAddress; | 26 | private readonly IntPtr newCabNamesCallBackAddress; |
| 27 | 27 | ||
| 28 | /// <summary> | 28 | /// <summary> |
| 29 | /// Instantiate a new CabinetBuilder. | 29 | /// Instantiate a new CabinetBuilder. |
| @@ -38,7 +38,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | this.cabinetWorkItems = new Queue(); | 40 | this.cabinetWorkItems = new Queue(); |
| 41 | this.lockObject = new object(); | ||
| 42 | this.Messaging = messaging; | 41 | this.Messaging = messaging; |
| 43 | this.threadCount = threadCount; | 42 | this.threadCount = threadCount; |
| 44 | 43 | ||
| @@ -56,10 +55,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 56 | /// Enqueues a CabinetWorkItem to the queue. | 55 | /// Enqueues a CabinetWorkItem to the queue. |
| 57 | /// </summary> | 56 | /// </summary> |
| 58 | /// <param name="cabinetWorkItem">cabinet work item</param> | 57 | /// <param name="cabinetWorkItem">cabinet work item</param> |
| 59 | public void Enqueue(CabinetWorkItem cabinetWorkItem) | 58 | public void Enqueue(CabinetWorkItem cabinetWorkItem) => this.cabinetWorkItems.Enqueue(cabinetWorkItem); |
| 60 | { | ||
| 61 | this.cabinetWorkItems.Enqueue(cabinetWorkItem); | ||
| 62 | } | ||
| 63 | 59 | ||
| 64 | /// <summary> | 60 | /// <summary> |
| 65 | /// Create the queued cabinets. | 61 | /// Create the queued cabinets. |
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs index de357e53..9741fcd9 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs | |||
| @@ -171,7 +171,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 171 | return cabbingThreadCount; | 171 | return cabbingThreadCount; |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | |||
| 175 | /// <summary> | 174 | /// <summary> |
| 176 | /// Creates a work item to create a cabinet. | 175 | /// Creates a work item to create a cabinet. |
| 177 | /// </summary> | 176 | /// </summary> |
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs new file mode 100644 index 00000000..6943d345 --- /dev/null +++ b/src/WixToolset.Core.WindowsInstaller/Bind/OptimizeFileFacadesOrderCommand.cs | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
| 2 | |||
| 3 | namespace WixToolset.Core.WindowsInstaller.Bind | ||
| 4 | { | ||
| 5 | using System; | ||
| 6 | using System.Collections.Generic; | ||
| 7 | using WixToolset.Core.Bind; | ||
| 8 | |||
| 9 | internal class OptimizeFileFacadesOrderCommand | ||
| 10 | { | ||
| 11 | public OptimizeFileFacadesOrderCommand(List<FileFacade> fileFacades) | ||
| 12 | { | ||
| 13 | this.FileFacades = fileFacades; | ||
| 14 | } | ||
| 15 | |||
| 16 | public List<FileFacade> FileFacades { get; private set; } | ||
| 17 | |||
| 18 | public List<FileFacade> Execute() | ||
| 19 | { | ||
| 20 | this.FileFacades.Sort(FileFacadeOptimizer.Instance); | ||
| 21 | |||
| 22 | return this.FileFacades; | ||
| 23 | } | ||
| 24 | |||
| 25 | private class FileFacadeOptimizer : IComparer<FileFacade> | ||
| 26 | { | ||
| 27 | public static readonly FileFacadeOptimizer Instance = new FileFacadeOptimizer(); | ||
| 28 | |||
| 29 | public int Compare(FileFacade x, FileFacade y) | ||
| 30 | { | ||
| 31 | // TODO: Sort these facades even smarter by directory path and component id | ||
| 32 | // and maybe file size or file extension and other creative ideas to | ||
| 33 | // get optimal install speed out of MSI. | ||
| 34 | return String.Compare(x.ComponentRef, y.ComponentRef, StringComparison.Ordinal); | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | } | ||
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs index 9aab7b98..bf28b279 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/UpdateMediaSequencesCommand.cs | |||
| @@ -29,9 +29,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 29 | { | 29 | { |
| 30 | var lastSequence = 0; | 30 | var lastSequence = 0; |
| 31 | 31 | ||
| 32 | // Order by Component to group the files by directory. | 32 | foreach (var facade in this.FileFacades) |
| 33 | var optimized = this.OptimizedFileFacades(); | ||
| 34 | foreach (var facade in optimized) | ||
| 35 | { | 33 | { |
| 36 | facade.Sequence = ++lastSequence; | 34 | facade.Sequence = ++lastSequence; |
| 37 | } | 35 | } |
| @@ -43,8 +41,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 43 | var patchGroups = new Dictionary<int, List<FileFacade>>(); | 41 | var patchGroups = new Dictionary<int, List<FileFacade>>(); |
| 44 | 42 | ||
| 45 | // sequence the non-patch-added files | 43 | // sequence the non-patch-added files |
| 46 | var optimized = this.OptimizedFileFacades(); | 44 | foreach (var facade in this.FileFacades) |
| 47 | foreach (var facade in optimized) | ||
| 48 | { | 45 | { |
| 49 | if (null == mediaTuple) | 46 | if (null == mediaTuple) |
| 50 | { | 47 | { |
| @@ -108,13 +105,5 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 108 | } | 105 | } |
| 109 | } | 106 | } |
| 110 | } | 107 | } |
| 111 | |||
| 112 | private IEnumerable<FileFacade> OptimizedFileFacades() | ||
| 113 | { | ||
| 114 | // TODO: Sort these facades even smarter by directory path and component id | ||
| 115 | // and maybe file size or file extension and other creative ideas to | ||
| 116 | // get optimal install speed out of MSI. | ||
| 117 | return this.FileFacades.OrderBy(f => f.ComponentRef); | ||
| 118 | } | ||
| 119 | } | 108 | } |
| 120 | } | 109 | } |
