@joebigelow / wix / commits / d5673c53

Implement cab thread count

Closes 6978

Rob Mensching committed Nov 6, 2022 at 19:29 UTC d5673c535ea6ce81e87e891746ac14088aee0184
3 files changed +41 -16
src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
+16 -13
@@ -83,17 +83,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
83
84 public void Execute()
85 {
86 - // If the cabbing thread count wasn't provided, default the number of cabbing threads to the number of processors.
87 - if (this.CabbingThreadCount <= 0)
88 - {
89 - this.CabbingThreadCount = this.CalculateCabbingThreadCount();
90 -
91 - this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString()));
92 - }
86 + var calculatedCabbingThreadCount = this.CalculateCabbingThreadCount();
87
88 this.GetMediaTemplateAttributes(out var maximumCabinetSizeForLargeFileSplitting, out var maximumUncompressedMediaSize);
89
96 - var cabinetBuilder = new CabinetBuilder(this.Messaging, this.CabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize);
90 + var cabinetBuilder = new CabinetBuilder(this.Messaging, calculatedCabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize);
91
92 var hashesByFileId = this.Section.Symbols.OfType<MsiFileHashSymbol>().ToDictionary(s => s.Id.Id);
93
@@ -130,16 +124,25 @@ namespace WixToolset.Core.WindowsInstaller.Bind
124
125 private int CalculateCabbingThreadCount()
126 {
133 - var cabbingThreadCount = Environment.ProcessorCount;
127 + var processorCount = Environment.ProcessorCount;
128
135 - if (cabbingThreadCount <= 0)
129 + // If the number of processors is invalid, default to a single processor.
130 + if (processorCount == 0)
131 {
137 - cabbingThreadCount = 1; // reset to 1 when the environment variable is invalid.
132 + processorCount = 1;
133
139 - this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), cabbingThreadCount.ToString()));
134 + this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), processorCount.ToString()));
135 }
136
142 - return cabbingThreadCount;
137 + // If the cabbing thread count was provided, and it isn't more than double the number of processors, use it.
138 + if (this.CabbingThreadCount > 0 && processorCount < this.CabbingThreadCount * 2)
139 + {
140 + processorCount = this.CabbingThreadCount;
141 + }
142 +
143 + this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(processorCount.ToString()));
144 +
145 + return processorCount;
146 }
147
148 private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable<IFileFacade> fileFacades, Dictionary<string, MsiFileHashSymbol> hashesByFileId)
src/wix/WixToolset.Core/CommandLine/BuildCommand.cs
+24 -3
@@ -52,6 +52,7 @@ namespace WixToolset.Core.CommandLine
52 new CommandLineHelpSwitch("-bindpath:target", "-bt", "Bind path to search for target package's content files. Only used when building a patch."),
53 new CommandLineHelpSwitch("-bindpath:update", "-bu", "Bind path to search for update package's content files. Only used when building a patch."),
54 new CommandLineHelpSwitch("-cabcache", "-cc", "Set a folder to cache cabinets across builds."),
55 + new CommandLineHelpSwitch("-cabthreads", "-ct", "Override the number of threads used to create cabinets."),
56 new CommandLineHelpSwitch("-culture", "Adds a culture to filter localization files."),
57 new CommandLineHelpSwitch("-define", "-d", "Sets a preprocessor variable."),
58 new CommandLineHelpSwitch("-defaultcompressionlevel", "-dcl", "Default compression level; see Compression levels below."),
@@ -147,7 +148,7 @@ namespace WixToolset.Core.CommandLine
148 {
149 using (new IntermediateFieldContext("wix.bind"))
150 {
150 - this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths, inputsOutputs, cancellationToken);
151 + this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.CabbingThreadCount, this.commandLine.BindPaths, inputsOutputs, cancellationToken);
152 }
153 }
154 }
@@ -265,7 +266,7 @@ namespace WixToolset.Core.CommandLine
266 return linker.Link(context);
267 }
268
268 - private void BindPhase(Intermediate output, IReadOnlyCollection<Localization> localizations, IReadOnlyCollection<string> filterCultures, string cabCachePath, IReadOnlyCollection<IBindPath> bindPaths, InputsAndOutputs inputsOutputs, CancellationToken cancellationToken)
269 + private void BindPhase(Intermediate output, IReadOnlyCollection<Localization> localizations, IReadOnlyCollection<string> filterCultures, string cabCachePath, int cabbingThreadCount, IReadOnlyCollection<IBindPath> bindPaths, InputsAndOutputs inputsOutputs, CancellationToken cancellationToken)
270 {
271 IResolveResult resolveResult;
272 {
@@ -295,7 +296,7 @@ namespace WixToolset.Core.CommandLine
296 {
297 var context = this.ServiceProvider.GetService<IBindContext>();
298 context.BindPaths = bindPaths;
298 - //context.CabbingThreadCount = this.CabbingThreadCount;
299 + context.CabbingThreadCount = cabbingThreadCount;
300 context.CabCachePath = cabCachePath;
301 context.ResolvedCodepage = resolveResult.Codepage;
302 context.ResolvedSummaryInformationCodepage = resolveResult.SummaryInformationCodepage;
@@ -467,6 +468,8 @@ namespace WixToolset.Core.CommandLine
468
469 public string CabCachePath { get; private set; }
470
471 + public int CabbingThreadCount { get; private set; }
472 +
473 public List<string> Cultures { get; } = new List<string>();
474
475 public List<string> Defines { get; } = new List<string>();
@@ -566,6 +569,24 @@ namespace WixToolset.Core.CommandLine
569 this.CabCachePath = parser.GetNextArgumentOrError(arg);
570 return true;
571
572 + case "ct":
573 + case "cabthreads":
574 + {
575 + var value = parser.GetNextArgumentOrError(arg);
576 + if (Int32.TryParse(value, out var cabbingThreads))
577 + {
578 + this.CabbingThreadCount = cabbingThreads;
579 + }
580 + else if (!String.IsNullOrEmpty(value))
581 + {
582 + var processorCount = Environment.ProcessorCount == 0 ? 1 : Environment.ProcessorCount;
583 + var range = Enumerable.Range(1, processorCount * 2).Select(i => i.ToString());
584 + parser.ReportErrorArgument(arg, ErrorMessages.IllegalCommandLineArgumentValue(arg, value, range));
585 + }
586 +
587 + return true;
588 + }
589 +
590 case "culture":
591 parser.GetNextArgumentOrError(arg, this.Cultures);
592 return true;
src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs
+1
@@ -28,6 +28,7 @@ namespace WixToolsetTest.CoreIntegration
28 "build",
29 Path.Combine(folder, "Package.wxs"),
30 Path.Combine(folder, "PackageComponents.wxs"),
31 + "-ct", "1000000",
32 "-d", "MediaTemplateCompressionLevel",
33 "-loc", Path.Combine(folder, "Package.en-us.wxl"),
34 "-bindpath", Path.Combine(folder, "data"),