From 2da31065e9201d8aaa16a81713b935e5d6343b39 Mon Sep 17 00:00:00 2001 From: halgari Date: Wed, 12 Jun 2024 15:07:12 -0600 Subject: [PATCH] Fix a bug with retractions when used with Hashed blobs --- src/NexusMods.MnemonicDB.Abstractions/Datom.cs | 15 +++++++++++++++ .../ITransaction.cs | 6 ++++++ .../TxFunctions/ExtensionMethods.cs | 6 ++---- .../InternalTransaction.cs | 6 ++++++ src/NexusMods.MnemonicDB/Transaction.cs | 7 +++++++ .../ABackendTest.cs | 1 + 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/NexusMods.MnemonicDB.Abstractions/Datom.cs b/src/NexusMods.MnemonicDB.Abstractions/Datom.cs index c45140f3..86643dcc 100644 --- a/src/NexusMods.MnemonicDB.Abstractions/Datom.cs +++ b/src/NexusMods.MnemonicDB.Abstractions/Datom.cs @@ -109,4 +109,19 @@ public int Compare(Datom other, IndexType indexType) throw new ArgumentOutOfRangeException(nameof(indexType), indexType, "Unknown index type"); } } + + /// + /// Clone this datom and return it as a retraction datom + /// + /// + public Datom Retract() + { + var data = GC.AllocateUninitializedArray(RawSpan.Length); + var dataSpan = data.AsSpan(); + RawSpan.CopyTo(dataSpan); + var prefix = MemoryMarshal.Read(dataSpan); + var newPrefix = new KeyPrefix().Set(prefix.E, prefix.A, TxId.Tmp, true); + MemoryMarshal.Write(dataSpan, newPrefix); + return new Datom(data, registry); + } } diff --git a/src/NexusMods.MnemonicDB.Abstractions/ITransaction.cs b/src/NexusMods.MnemonicDB.Abstractions/ITransaction.cs index 6b0898f5..28b9fdcb 100644 --- a/src/NexusMods.MnemonicDB.Abstractions/ITransaction.cs +++ b/src/NexusMods.MnemonicDB.Abstractions/ITransaction.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.DatomIterators; using NexusMods.MnemonicDB.Abstractions.Models; using NexusMods.MnemonicDB.Abstractions.TxFunctions; @@ -59,6 +60,11 @@ public interface ITransaction : IDisposable void Retract(EntityId entityId, Attribute attribute, TVal val) => Add(entityId, attribute, val, isRetract: true); + /// + /// Retract a specific datom + /// + void Add(Datom datom); + /// /// Commits the transaction /// diff --git a/src/NexusMods.MnemonicDB.Abstractions/TxFunctions/ExtensionMethods.cs b/src/NexusMods.MnemonicDB.Abstractions/TxFunctions/ExtensionMethods.cs index f2d480a7..b28f2f4a 100644 --- a/src/NexusMods.MnemonicDB.Abstractions/TxFunctions/ExtensionMethods.cs +++ b/src/NexusMods.MnemonicDB.Abstractions/TxFunctions/ExtensionMethods.cs @@ -92,11 +92,9 @@ private static bool ShouldRecursiveDelete(IDb db, IReadDatom referenceDatom) private static void DeleteThisOnly(ITransaction tx, IDb db, EntityId eid) { - var segment = db.Get(eid); - foreach (var datom in segment) + foreach (var datom in db.Get(eid)) { - var resolved = datom.Resolved; - resolved.Retract(tx); + tx.Add(datom.Retract()); } } } diff --git a/src/NexusMods.MnemonicDB.Storage/InternalTransaction.cs b/src/NexusMods.MnemonicDB.Storage/InternalTransaction.cs index 141f692e..f8e4f77f 100644 --- a/src/NexusMods.MnemonicDB.Storage/InternalTransaction.cs +++ b/src/NexusMods.MnemonicDB.Storage/InternalTransaction.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using NexusMods.MnemonicDB.Abstractions; using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.DatomIterators; using NexusMods.MnemonicDB.Abstractions.IndexSegments; using NexusMods.MnemonicDB.Abstractions.Models; using NexusMods.MnemonicDB.Abstractions.TxFunctions; @@ -57,6 +58,11 @@ public void Attach(ITemporaryEntity entity) _temporaryEntities.Add(entity); } + public void Add(Datom datom) + { + datoms.Add(datom.RawSpan); + } + /// public Task Commit() { diff --git a/src/NexusMods.MnemonicDB/Transaction.cs b/src/NexusMods.MnemonicDB/Transaction.cs index 9c4e0f58..f2a0fded 100644 --- a/src/NexusMods.MnemonicDB/Transaction.cs +++ b/src/NexusMods.MnemonicDB/Transaction.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using NexusMods.MnemonicDB.Abstractions; using NexusMods.MnemonicDB.Abstractions.Attributes; +using NexusMods.MnemonicDB.Abstractions.DatomIterators; using NexusMods.MnemonicDB.Abstractions.IndexSegments; using NexusMods.MnemonicDB.Abstractions.Internals; using NexusMods.MnemonicDB.Abstractions.Models; @@ -52,6 +53,12 @@ public void Add(EntityId entityId, ReferencesAttribute attribute, IEnumerable + public void Add(Datom datom) + { + _datoms.Add(datom.RawSpan); + } + public void Add(ITxFunction fn) { if (_committed) diff --git a/tests/NexusMods.MnemonicDB.Storage.Tests/ABackendTest.cs b/tests/NexusMods.MnemonicDB.Storage.Tests/ABackendTest.cs index ea19ddc2..a5dd723a 100644 --- a/tests/NexusMods.MnemonicDB.Storage.Tests/ABackendTest.cs +++ b/tests/NexusMods.MnemonicDB.Storage.Tests/ABackendTest.cs @@ -107,6 +107,7 @@ public async Task CanStoreDataInBlobs(IndexType type) await Verify(datoms.ToTable(Registry)) .UseDirectory("BackendTestVerifyData") .UseParameters(type); + }