diff --git a/Wabbajack.Common/Utils.cs b/Wabbajack.Common/Utils.cs index e4eeeadb..73d2e57d 100644 --- a/Wabbajack.Common/Utils.cs +++ b/Wabbajack.Common/Utils.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Net.Http; using System.Reactive.Subjects; using System.Reflection; +using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using System.Threading; @@ -838,11 +839,10 @@ namespace Wabbajack.Common private static Dictionary _cachedDiskSpeeds = new Dictionary(); public static async Task TestDiskSpeed(WorkQueue queue, string path) { - var driveName = Volume.GetUniqueVolumeNameForPath(path); - if (_cachedDiskSpeeds.TryGetValue(driveName, out long speed)) + if (_cachedDiskSpeeds.TryGetValue(path, out long speed)) return speed; speed = await TestDiskSpeedInner(queue, path); - _cachedDiskSpeeds[driveName] = speed; + _cachedDiskSpeeds[path] = speed; return speed; } @@ -977,5 +977,35 @@ namespace Wabbajack.Common public int code; public string message; } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class MEMORYSTATUSEX + { + public uint dwLength; + public uint dwMemoryLoad; + public ulong ullTotalPhys; + public ulong ullAvailPhys; + public ulong ullTotalPageFile; + public ulong ullAvailPageFile; + public ulong ullTotalVirtual; + public ulong ullAvailVirtual; + public ulong ullAvailExtendedVirtual; + public MEMORYSTATUSEX() + { + dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); + } + } + + + [return: MarshalAs(UnmanagedType.Bool)] + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer); + + public static MEMORYSTATUSEX GetMemoryStatus() + { + var mstat = new MEMORYSTATUSEX(); + GlobalMemoryStatusEx(mstat); + return mstat; + } } } diff --git a/Wabbajack.Lib/AInstaller.cs b/Wabbajack.Lib/AInstaller.cs index dc67127e..23dfd790 100644 --- a/Wabbajack.Lib/AInstaller.cs +++ b/Wabbajack.Lib/AInstaller.cs @@ -325,11 +325,14 @@ namespace Wabbajack.Lib public async Task RecommendQueueSize() { - var output_size = await RecommendQueueSize(OutputFolder); - var download_size = await RecommendQueueSize(DownloadFolder); + const ulong GB = (1024 * 1024 * 1024); + // Most of the heavy lifting is done on the scratch disk, so we'll use the value from that disk + var memory = Utils.GetMemoryStatus(); + // Assume roughly 2GB of ram needed to extract each 7zip archive, and then leave 2GB for the OS + var based_on_memory = (memory.ullTotalPhys - (2 * GB)) / (2 * GB); var scratch_size = await RecommendQueueSize(Directory.GetCurrentDirectory()); - var result = Math.Min(output_size, Math.Min(download_size, scratch_size)); - Utils.Log($"Recommending a queue size of {result} based on disk performance and number of cores"); + var result = Math.Min((int)based_on_memory, (int)scratch_size); + Utils.Log($"Recommending a queue size of {result} based on disk performance, number of cores, and {((long)memory.ullTotalPhys).ToFileSizeString()} of system RAM"); return result; }