diff --git a/Compression.BSA.Test/BSATests.cs b/Compression.BSA.Test/BSATests.cs index 51a0bbb5..7e61777c 100644 --- a/Compression.BSA.Test/BSATests.cs +++ b/Compression.BSA.Test/BSATests.cs @@ -99,6 +99,7 @@ namespace Compression.BSA.Test TestContext.WriteLine($"Reading {bsa}"); string tempFile = Path.Combine("tmp.bsa"); + var size = File.GetSize(bsa); using (var a = BSADispatch.OpenRead(bsa)) { await a.Files.PMap(Queue, file => @@ -120,7 +121,7 @@ namespace Compression.BSA.Test Console.WriteLine($"Building {bsa}"); - using (var w = ViaJson(a.State).MakeBuilder()) + using (var w = ViaJson(a.State).MakeBuilder(size)) { var streams = await a.Files.PMap(Queue, file => { diff --git a/Compression.BSA/BA2Builder.cs b/Compression.BSA/BA2Builder.cs index 7b77e54a..a7c173ce 100644 --- a/Compression.BSA/BA2Builder.cs +++ b/Compression.BSA/BA2Builder.cs @@ -27,10 +27,10 @@ namespace Compression.BSA private List _entries = new List(); private DiskSlabAllocator _slab; - public BA2Builder(BA2StateObject state) + public BA2Builder(BA2StateObject state, long size) { _state = state; - _slab = new DiskSlabAllocator(); + _slab = new DiskSlabAllocator(size); } public void Dispose() diff --git a/Compression.BSA/BA2Reader.cs b/Compression.BSA/BA2Reader.cs index 1f00f7ef..c5a1d055 100644 --- a/Compression.BSA/BA2Reader.cs +++ b/Compression.BSA/BA2Reader.cs @@ -125,9 +125,9 @@ namespace Compression.BSA public EntryType Type { get; set; } public string HeaderMagic { get; set; } public uint Version { get; set; } - public override IBSABuilder MakeBuilder() + public override IBSABuilder MakeBuilder(long size) { - return new BA2Builder(this); + return new BA2Builder(this, size); } } diff --git a/Compression.BSA/BSABuilder.cs b/Compression.BSA/BSABuilder.cs index 628a21df..fa434990 100644 --- a/Compression.BSA/BSABuilder.cs +++ b/Compression.BSA/BSABuilder.cs @@ -25,14 +25,14 @@ namespace Compression.BSA internal uint _version; internal DiskSlabAllocator _slab; - public BSABuilder() + public BSABuilder(long size) { _fileId = Encoding.ASCII.GetBytes("BSA\0"); _offset = 0x24; - _slab = new DiskSlabAllocator(); + _slab = new DiskSlabAllocator(size); } - public BSABuilder(BSAStateObject bsaStateObject) : this() + public BSABuilder(BSAStateObject bsaStateObject, long size) : this(size) { _version = bsaStateObject.Version; _fileFlags = bsaStateObject.FileFlags; diff --git a/Compression.BSA/BSAReader.cs b/Compression.BSA/BSAReader.cs index de92c4d6..5d239091 100644 --- a/Compression.BSA/BSAReader.cs +++ b/Compression.BSA/BSAReader.cs @@ -163,9 +163,9 @@ namespace Compression.BSA } - public override IBSABuilder MakeBuilder() + public override IBSABuilder MakeBuilder(long size) { - return new BSABuilder(this); + return new BSABuilder(this, size); } public string Magic { get; set; } diff --git a/Compression.BSA/IBSAReader.cs b/Compression.BSA/IBSAReader.cs index 4bcfc23c..ddec769a 100644 --- a/Compression.BSA/IBSAReader.cs +++ b/Compression.BSA/IBSAReader.cs @@ -22,7 +22,7 @@ namespace Compression.BSA public class ArchiveStateObject { - public virtual IBSABuilder MakeBuilder() + public virtual IBSABuilder MakeBuilder(long size) { throw new NotImplementedException(); } diff --git a/Compression.BSA/TES3Reader.cs b/Compression.BSA/TES3Reader.cs index 28ff9a64..11462a95 100644 --- a/Compression.BSA/TES3Reader.cs +++ b/Compression.BSA/TES3Reader.cs @@ -87,7 +87,7 @@ namespace Compression.BSA public uint HashOffset { get; set; } public uint VersionNumber { get; set; } - public override IBSABuilder MakeBuilder() + public override IBSABuilder MakeBuilder(long size) { return new TES3Builder(this); } diff --git a/Wabbajack.Common/Util/DiskSlabAllocator.cs b/Wabbajack.Common/Util/DiskSlabAllocator.cs index effdee3b..4e108e5e 100644 --- a/Wabbajack.Common/Util/DiskSlabAllocator.cs +++ b/Wabbajack.Common/Util/DiskSlabAllocator.cs @@ -14,11 +14,13 @@ namespace Wabbajack.Common private MemoryMappedFile _mmap; private long _head = 0; private string _name; + private FileStream _fileStream; - public DiskSlabAllocator() + public DiskSlabAllocator(long size) { - _name = Guid.NewGuid().ToString(); - _mmap = MemoryMappedFile.CreateNew(null, (long)1 << 34); + _file = new TempFile(); + _fileStream = _file.File.Open(FileMode.Create, FileAccess.ReadWrite); + _mmap = MemoryMappedFile.CreateFromFile(_fileStream, null, size, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false); } public Stream Allocate(long size) @@ -34,6 +36,8 @@ namespace Wabbajack.Common public void Dispose() { _mmap?.Dispose(); + _fileStream?.Dispose(); + _file?.Dispose(); } } } diff --git a/Wabbajack.Lib/MO2Installer.cs b/Wabbajack.Lib/MO2Installer.cs index 6a7b23f2..acb2238b 100644 --- a/Wabbajack.Lib/MO2Installer.cs +++ b/Wabbajack.Lib/MO2Installer.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel.DataAnnotations; using System.Globalization; using System.IO; using System.Linq; @@ -237,7 +238,9 @@ namespace Wabbajack.Lib Status($"Building {bsa.To}"); var sourceDir = Path.Combine(OutputFolder, Consts.BSACreationDir, bsa.TempID); - using (var a = bsa.State.MakeBuilder()) + var bsaSize = bsa.FileStates.Select(state => File.GetSize(Path.Combine(sourceDir, state.Path))).Sum(); + + using (var a = bsa.State.MakeBuilder(bsaSize)) { var streams = await bsa.FileStates.PMap(Queue, state => {