wabbajack/Wabbajack.Common/Util/DiskSlabAllocator.cs

52 lines
1.7 KiB
C#
Raw Normal View History

using System;
2020-04-03 03:57:59 +00:00
using System.Collections.Generic;
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
{
private readonly TempFile _file;
private readonly MemoryMappedFile _mmap;
private long _head = 0;
private readonly FileStream _fileStream;
2020-04-03 03:57:59 +00:00
private List<IDisposable> _allocated = new List<IDisposable>();
private long _size;
2020-03-09 20:38:35 +00:00
public DiskSlabAllocator(long size)
{
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);
}
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}");
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;
}
}
public void Dispose()
{
2020-04-03 03:57:59 +00:00
_allocated.Do(s => s.Dispose());
_mmap?.Dispose();
2020-03-09 20:38:35 +00:00
_fileStream?.Dispose();
_file?.Dispose();
}
}
}