Files
HawkeyeVision/framework/Inspectron.Fastbuffer/IndexFile.cs
2025-09-05 11:11:23 +02:00

137 lines
4.0 KiB
C#

using System.Text;
using Inspectron.Fastbuffer.Interfaces;
using OpenCvSharp;
using Serilog;
namespace Inspectron.Fastbuffer;
public class IndexFile
{
private readonly string _indexFilePath;
private readonly int _bufferSize;
private readonly IFilesystem _filesystem;
private readonly string? _bufferPath;
private const int RecordSize = 512;
private const int IndexSize = 4;
private const int HeaderSize = 4;
public IndexFile(string path, int bufferSize, IFilesystem filesystem)
{
_indexFilePath = path;
_bufferSize = bufferSize;
_filesystem = filesystem;
ValidateFile();
_bufferPath = Path.Combine(Path.GetDirectoryName(_indexFilePath), "..");
}
private void ValidateFile()
{
if (!File.Exists(_indexFilePath))
{
CreateFile();
}
// check file size
var fileInfo = new FileInfo(_indexFilePath);
if (fileInfo.Length != _bufferSize * RecordSize + HeaderSize)
{
UpdateFile();
}
}
private void UpdateFile()
{
using var fileStream = File.Open(_indexFilePath, FileMode.Open);
var actualSize = fileStream.Length;
if (actualSize < _bufferSize+ HeaderSize)
{
fileStream.Seek(0, SeekOrigin.End);
var buffer = new byte[_bufferSize * RecordSize - actualSize];
fileStream.Write(buffer, HeaderSize, buffer.Length);
}
}
private void CreateFile()
{
using var fileStream = File.Create(_indexFilePath);
var buffer = new byte[_bufferSize* RecordSize + HeaderSize];
fileStream.Write(buffer, 0, buffer.Length);
fileStream.Seek(0, SeekOrigin.Begin);
var bytes = BitConverter.GetBytes(-1);
fileStream.Write(bytes, 0, bytes.Length);
}
public int GetCurrentArtifactId()
{
using var fileStream = File.Open(_indexFilePath, FileMode.Open);
using var reader = new BinaryReader(fileStream);
return reader.ReadInt32();
}
public void SetCurrentArtifactId(int id)
{
using var fileStream = File.Open(_indexFilePath, FileMode.Open);
using var writer = new BinaryWriter(fileStream);
writer.Write(id);
}
public string GetArtifactPath(int id)
{
using var fileStream = File.Open(_indexFilePath, FileMode.Open);
fileStream.Seek(id * RecordSize+HeaderSize, SeekOrigin.Begin);
byte[] bytes = new byte[RecordSize];
fileStream.Read(bytes, 0, RecordSize);
return Encoding.UTF8.GetString(bytes).TrimEnd('\0');
}
public int GetNextId()
{
var currentId = GetCurrentArtifactId();
if (currentId + 1 >= _bufferSize)
{
currentId = 0;
}
else
{
currentId++;
}
return currentId;
}
public void DeleteArtifact(int id)
{
var relPath = GetArtifactPath(id);
var filePath = Path.Combine(_bufferPath, relPath);
try
{
_filesystem.Delete(filePath);
}
catch (Exception e)
{
Log.Error("Error deleting artifact {id}: {message}",id,e.Message);
}
}
public void WriteNextArtifact(Mat data, string fileName)
{
var id = GetNextId();
Log.Debug("Writing artifact {id}",id);
var existingPath = GetArtifactPath(id);
Log.Debug("Existing path: {existingPath}", existingPath);
DeleteArtifact(id);
var filePath = Path.Combine(_bufferPath, fileName);
_filesystem.Write(filePath, data);
SetCurrentArtifactId(id);
using var fileStream = File.Open(_indexFilePath, FileMode.Open);
fileStream.Seek(id * RecordSize+ HeaderSize, SeekOrigin.Begin);
var bytes = Encoding.UTF8.GetBytes(fileName);
fileStream.Write(bytes, 0, bytes.Length);
var padding = new byte[RecordSize - bytes.Length];
fileStream.Write(padding, 0, padding.Length);
}
}