using System;
using System.Globalization;
using System.IO;
using System.Text;
using FASTER.core;
namespace PerfectNumbers.Core.Persistence;
///
/// Stores per-prime BitContradiction solver state (arbitrary string payload) using Microsoft.FASTER.Core.
/// No LMDB migration is performed for this repository.
///
public sealed class BitContradictionStateRepository : IDisposable
{
private readonly FasterKV _store;
private readonly IDevice _logDevice;
private readonly IDevice _objectLogDevice;
private static readonly Encoding Utf8 = Encoding.UTF8;
public string DatabasePath { get; }
public static BitContradictionStateRepository Open(string directory, string repositoryFileName = "bitcontradiction.solver.faster")
{
Directory.CreateDirectory(directory);
string dbPath = Path.Combine(directory, repositoryFileName);
return new BitContradictionStateRepository(dbPath);
}
private BitContradictionStateRepository(string path)
{
DatabasePath = path;
_logDevice = Devices.CreateLogDevice(path + ".log");
_objectLogDevice = Devices.CreateLogDevice(path + ".obj.log");
_store = new FasterKV(
1L << 20,
new LogSettings
{
LogDevice = _logDevice,
ObjectLogDevice = _objectLogDevice,
});
}
public void Upsert(ulong prime, string state)
{
using var session = _store.For(new SimpleFunctions()).NewSession>();
string keyString = prime.ToString(CultureInfo.InvariantCulture);
session.Upsert(keyString, state);
session.CompletePending(true);
}
public bool TryGet(ulong prime, out string? state)
{
using var session = _store.For(new SimpleFunctions()).NewSession>();
string keyString = prime.ToString(CultureInfo.InvariantCulture);
if (session.Read(keyString, out string? stored).Found)
{
state = stored;
return true;
}
state = null;
return false;
}
public void Dispose()
{
_store.Dispose();
_logDevice.Dispose();
_objectLogDevice.Dispose();
}
}