check point
This commit is contained in:
150
framework/Inspectron.Fastbuffer/IndexFile.cs
Normal file
150
framework/Inspectron.Fastbuffer/IndexFile.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using System.Text;
|
||||
using Inspectron.Fastbuffer.Interfaces;
|
||||
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(byte[] 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);
|
||||
}
|
||||
|
||||
public byte[] ReadArtifact(int id)
|
||||
{
|
||||
using var fileStream = File.Open(_indexFilePath, FileMode.Open);
|
||||
fileStream.Seek(id * RecordSize+ HeaderSize, SeekOrigin.Begin);
|
||||
var bytes = new byte[RecordSize];
|
||||
fileStream.Read(bytes, 0, RecordSize);
|
||||
var fileName = Encoding.UTF8.GetString(bytes).TrimEnd('\0');
|
||||
var filePath = Path.Combine(_bufferPath, fileName);
|
||||
return _filesystem.Read(filePath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user