using Inspectron.Fastbuffer.Interfaces; using System.Collections.Concurrent; namespace Inspectron.Fastbuffer.Filesystems; public class AsyncFilesystem : IFilesystem { private readonly DirectFilesystem _directFilesystem = new(); private readonly ConcurrentDictionary _buffer = new(); private readonly BlockingCollection<(string path, byte[] data)> _writeQueue = new(); private readonly Thread _backgroundThread; private readonly object _lock = new(); public AsyncFilesystem() { _backgroundThread = new Thread(ProcessWriteQueue) { IsBackground = true }; _backgroundThread.Name= "AsyncFilesystem"; _backgroundThread.Start(); } public void Write(string path, byte[] data) { lock (_lock) { _buffer[path] = data; _writeQueue.Add((path, data)); } } public byte[] Read(string path) { lock (_lock) { if (_buffer.TryGetValue(path, out var data)) { return data; } } return _directFilesystem.Read(path); } public void Delete(string path) { lock (_lock) { // pats is in buffer, so it's not written to disk yet if (_buffer.TryRemove(path, out _)) { return; } _directFilesystem.Delete(path); } } private void ProcessWriteQueue() { foreach (var (path, data) in _writeQueue.GetConsumingEnumerable()) { _directFilesystem.Write(path, data); lock (_lock) _buffer.TryRemove(path, out _); } } public void Dispose() { _writeQueue.CompleteAdding(); _backgroundThread.Join(); } public void Clear() { lock (_lock) { while (_writeQueue.TryTake(out _)) { } } } }