2020-03-05 00:02:16 +00:00
|
|
|
|
using System;
|
2020-04-03 03:57:59 +00:00
|
|
|
|
using System.Collections.Generic;
|
2020-03-05 00:02:16 +00:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.IO.MemoryMappedFiles;
|
|
|
|
|
|
|
|
|
|
namespace Wabbajack.Common
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Memory allocator that stores data via memory mapping to a on-disk file. Disposing of this object
|
|
|
|
|
/// deletes the memory mapped file
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class DiskSlabAllocator : IDisposable
|
|
|
|
|
{
|
2020-03-28 13:33:39 +00:00
|
|
|
|
private readonly TempFile _file;
|
|
|
|
|
private readonly MemoryMappedFile _mmap;
|
2020-03-05 00:02:16 +00:00
|
|
|
|
private long _head = 0;
|
2020-03-28 13:33:39 +00:00
|
|
|
|
private readonly FileStream _fileStream;
|
2020-04-03 03:57:59 +00:00
|
|
|
|
private List<IDisposable> _allocated = new List<IDisposable>();
|
|
|
|
|
private long _size;
|
2020-03-05 00:02:16 +00:00
|
|
|
|
|
2020-03-09 20:38:35 +00:00
|
|
|
|
public DiskSlabAllocator(long size)
|
2020-03-05 00:02:16 +00:00
|
|
|
|
{
|
2020-03-09 20:38:35 +00:00
|
|
|
|
_file = new TempFile();
|
|
|
|
|
_fileStream = _file.File.Open(FileMode.Create, FileAccess.ReadWrite);
|
2020-04-03 03:57:59 +00:00
|
|
|
|
_size = size;
|
2020-03-09 20:38:35 +00:00
|
|
|
|
_mmap = MemoryMappedFile.CreateFromFile(_fileStream, null, size, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, false);
|
2020-03-05 00:02:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Stream Allocate(long size)
|
|
|
|
|
{
|
|
|
|
|
lock (this)
|
|
|
|
|
{
|
2020-04-03 03:57:59 +00:00
|
|
|
|
if (_head + size >= _size)
|
|
|
|
|
throw new InvalidDataException($"Size out of range. Declared {_size} used {_head + size}");
|
2020-03-05 00:02:16 +00:00
|
|
|
|
var startAt = _head;
|
|
|
|
|
_head += size;
|
2020-04-03 03:57:59 +00:00
|
|
|
|
var stream = _mmap.CreateViewStream(startAt, size, MemoryMappedFileAccess.ReadWrite);
|
|
|
|
|
_allocated.Add(stream);
|
|
|
|
|
return stream;
|
2020-03-05 00:02:16 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2020-04-03 03:57:59 +00:00
|
|
|
|
_allocated.Do(s => s.Dispose());
|
2020-03-05 00:02:16 +00:00
|
|
|
|
_mmap?.Dispose();
|
2020-03-09 20:38:35 +00:00
|
|
|
|
_fileStream?.Dispose();
|
|
|
|
|
_file?.Dispose();
|
2020-03-05 00:02:16 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|