2021-09-27 12:42:46 +00:00
|
|
|
using System.Collections.Concurrent;
|
|
|
|
using System.IO;
|
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using Wabbajack.Paths.IO;
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
namespace Wabbajack.Compression.BSA;
|
|
|
|
|
|
|
|
public class DiskSlabAllocator
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
private readonly ConcurrentBag<TemporaryPath> _files = new();
|
|
|
|
private readonly TemporaryFileManager _manager;
|
|
|
|
private readonly long _maxMemorySize;
|
|
|
|
private readonly ConcurrentBag<Stream> _streams = new();
|
|
|
|
private long _memorySize;
|
|
|
|
|
|
|
|
public DiskSlabAllocator(TemporaryFileManager manager, long maxMemorySize = 1024 * 1024 * 256)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
_manager = manager;
|
|
|
|
_memorySize = 0;
|
|
|
|
_maxMemorySize = maxMemorySize;
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public async Task DisposeAsync()
|
|
|
|
{
|
|
|
|
foreach (var s in _streams)
|
|
|
|
await s.DisposeAsync();
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
foreach (var file in _files) file.Dispose();
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public Stream Allocate(long rLength)
|
|
|
|
{
|
|
|
|
var newSize = Interlocked.Add(ref _memorySize, rLength);
|
|
|
|
if (newSize < _maxMemorySize)
|
|
|
|
{
|
|
|
|
var stream = new MemoryStream();
|
|
|
|
_streams.Add(stream);
|
|
|
|
return stream;
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
2021-10-23 16:51:17 +00:00
|
|
|
else
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
var tempFile = _manager.CreateFile();
|
|
|
|
var stream = tempFile.Path.Open(FileMode.Create, FileAccess.ReadWrite, FileShare.None);
|
|
|
|
_streams.Add(stream);
|
|
|
|
_files.Add(tempFile);
|
|
|
|
return stream;
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|