using Inspectron.Fastbuffer.Interfaces; using System.Collections.Concurrent; using OpenCvSharp; using Serilog; namespace Inspectron.Fastbuffer.Filesystems; public class AsyncFilesystem : IFilesystem { private readonly DirectFilesystem _directFilesystem = new(); private readonly List _buffer = new(); private readonly BlockingCollection<(string path, Mat 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, Mat data) { lock (_lock) { _buffer.Add(path); _writeQueue.Add((path, data)); } } public void Delete(string path) { lock (_lock) { // pats is in buffer, so it's not written to disk yet if (_buffer.Contains(path)) { _buffer.Remove(path); return; } _directFilesystem.Delete(path); } } private void ProcessWriteQueue() { foreach (var (path, data) in _writeQueue.GetConsumingEnumerable()) { _directFilesystem.Write(path, data); lock (_lock) _buffer.Remove(path); if (_writeQueue.Count > 5) Log.Warning($"AsyncFilesystem write queue size: {_writeQueue.Count}"); } } public void Dispose() { _writeQueue.CompleteAdding(); _backgroundThread.Join(); } public void Clear() { lock (_lock) { while (_writeQueue.TryTake(out _)) { } } } }