diff --git a/src/NexusMods.MnemonicDB.Abstractions/Attributes/TimestampAttribute.cs b/src/NexusMods.MnemonicDB.Abstractions/Attributes/TimestampAttribute.cs index 2cf3752..771a4e7 100644 --- a/src/NexusMods.MnemonicDB.Abstractions/Attributes/TimestampAttribute.cs +++ b/src/NexusMods.MnemonicDB.Abstractions/Attributes/TimestampAttribute.cs @@ -7,11 +7,11 @@ namespace NexusMods.MnemonicDB.Abstractions.Attributes; /// /// An attribute that holds a timestamp /// -public class TimestampAttribute(string ns, string name) : ScalarAttribute(ValueTag.Int64, ns, name) +public class TimestampAttribute(string ns, string name) : ScalarAttribute(ValueTag.Int64, ns, name) { /// - protected override long ToLowLevel(DateTime value) => value.ToFileTimeUtc(); + protected override long ToLowLevel(DateTimeOffset value) => value.ToUnixTimeMilliseconds(); /// - protected override DateTime FromLowLevel(long value, AttributeResolver resolver) => DateTime.FromFileTimeUtc(value); + protected override DateTimeOffset FromLowLevel(long value, AttributeResolver resolver) => DateTimeOffset.FromUnixTimeMilliseconds(value); } diff --git a/src/NexusMods.MnemonicDB/Caching/IndexSegmentCache.cs b/src/NexusMods.MnemonicDB/Caching/IndexSegmentCache.cs index 75dc4f4..9c128ad 100644 --- a/src/NexusMods.MnemonicDB/Caching/IndexSegmentCache.cs +++ b/src/NexusMods.MnemonicDB/Caching/IndexSegmentCache.cs @@ -63,18 +63,25 @@ public struct CacheValue : IEquatable public long LastAccessed; public readonly IndexSegment Segment; - public CacheValue(long lastAccessed, IndexSegment segment) + public CacheValue(IndexSegment segment) { - LastAccessed = lastAccessed; + LastAccessed = CreateLastAccessed(); Segment = segment; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static long CreateLastAccessed(TimeProvider? timeProvider = null) + { + timeProvider ??= TimeProvider.System; + return timeProvider.GetTimestamp(); + } + /// /// Update the last accessed time to now. /// public void Hit() { - LastAccessed = DateTime.UtcNow.Ticks; + LastAccessed = CreateLastAccessed(); } /// @@ -133,7 +140,7 @@ public bool TryGetValue(CacheKey key, out IndexSegment segment) /// public CacheRoot With(CacheKey key, IndexSegment segment, IndexSegmentCache cache) { - var newEntries = _entries.SetItem(key, new CacheValue(DateTime.UtcNow.Ticks, segment)); + var newEntries = _entries.SetItem(key, new CacheValue(segment)); if (newEntries.Count > cache._entryCapacity) { newEntries = PurgeEntries(newEntries, newEntries.Count / 10); diff --git a/src/NexusMods.MnemonicDB/Storage/DatomStore.cs b/src/NexusMods.MnemonicDB/Storage/DatomStore.cs index f30d0d4..fb1d026 100644 --- a/src/NexusMods.MnemonicDB/Storage/DatomStore.cs +++ b/src/NexusMods.MnemonicDB/Storage/DatomStore.cs @@ -3,6 +3,7 @@ using System.Collections.Frozen; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.InteropServices; using System.Threading; @@ -72,7 +73,7 @@ public sealed partial class DatomStore : IDatomStore /// private Thread? _loggerThread; - private CancellationTokenSource _shutdownToken = new(); + private readonly CancellationTokenSource _shutdownToken = new(); private TxId _thisTx; /// @@ -80,12 +81,20 @@ public sealed partial class DatomStore : IDatomStore /// private readonly Memory _txScratchSpace; + private readonly TimeProvider _timeProvider; + /// /// DI constructor /// - public DatomStore(ILogger logger, DatomStoreSettings settings, IStoreBackend backend, bool bootstrap = true) + public DatomStore( + ILogger logger, + DatomStoreSettings settings, + IStoreBackend backend, + TimeProvider? timeProvider = null, + bool bootstrap = true) { CurrentSnapshot = default!; + _timeProvider = timeProvider ?? TimeProvider.System; _txScratchSpace = new Memory(new byte[1024]); _remapFunc = Remap; _dbStream = new DbStream(); @@ -97,10 +106,9 @@ public DatomStore(ILogger logger, DatomStoreSettings settings, IStor _retractWriter = new PooledMemoryBufferWriter(); _prevWriter = new PooledMemoryBufferWriter(); - Logger = logger; _settings = settings; - + Backend.DeclareEAVT(IndexType.EAVTCurrent); Backend.DeclareEAVT(IndexType.EAVTHistory); Backend.DeclareAEVT(IndexType.AEVTCurrent); @@ -123,8 +131,7 @@ public DatomStore(ILogger logger, DatomStoreSettings settings, IStor AVETCurrent = Backend.GetIndex(IndexType.AVETCurrent); AVETHistory = Backend.GetIndex(IndexType.AVETHistory); - if (bootstrap) - Bootstrap(); + if (bootstrap) Bootstrap(); } /// @@ -411,7 +418,7 @@ internal void LogDatoms(IWriteBatch batch, TSource datoms, bool advanc /// private void LogTx(IWriteBatch batch) { - MemoryMarshal.Write(_txScratchSpace.Span, DateTime.UtcNow.ToFileTimeUtc()); + MemoryMarshal.Write(_txScratchSpace.Span, _timeProvider.GetTimestamp()); var id = EntityId.From(_thisTx.Value); var keyPrefix = new KeyPrefix(id, AttributeCache.GetAttributeId(MnemonicDB.Abstractions.BuiltInEntities.Transaction.Timestamp.Id), _thisTx, false, ValueTag.Int64); var datom = new Datom(keyPrefix, _txScratchSpace[..sizeof(long)]); diff --git a/tests/NexusMods.MnemonicDB.Tests/AMnemonicDBTest.cs b/tests/NexusMods.MnemonicDB.Tests/AMnemonicDBTest.cs index 5df7971..589175c 100644 --- a/tests/NexusMods.MnemonicDB.Tests/AMnemonicDBTest.cs +++ b/tests/NexusMods.MnemonicDB.Tests/AMnemonicDBTest.cs @@ -128,7 +128,7 @@ string TruncateOrPad(string val, int length) var hash = code.ToString("X16"); sb.Append($"Blob 0x{hash} {byteArray.Length} bytes".PadRight(48)); break; - case DateTime dateTime: + case DateTimeOffset: sb.Append($"DateTime : {dateTimeCount++}".PadRight(48)); break; default: