Skip to content

Commit

Permalink
Update how we get DB updates to also include the changed datoms
Browse files Browse the repository at this point in the history
  • Loading branch information
halgari committed Jun 10, 2024
1 parent 320bad7 commit 1b40bac
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 49 deletions.
25 changes: 24 additions & 1 deletion src/NexusMods.MnemonicDB.Abstractions/IConnection.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
using System;
using NexusMods.MnemonicDB.Abstractions.IndexSegments;
using NexusMods.MnemonicDB.Abstractions.Internals;

namespace NexusMods.MnemonicDB.Abstractions;

/// <summary>
/// A database revision, which includes a datom and the datoms added to it.
/// </summary>
public struct Revision
{
/// <summary>
/// The database for the most recent transaction
/// </summary>
public IDb Database;

/// <summary>
/// The datoms that were added in the most recent transaction
/// </summary>
public IndexSegment AddedDatoms;
}

/// <summary>
/// Represents a connection to a database.
/// </summary>
Expand All @@ -12,6 +30,11 @@ public interface IConnection
/// </summary>
public IDb Db { get; }

/// <summary>
/// The attribute registry for this connection
/// </summary>
public IAttributeRegistry Registry { get; }

/// <summary>
/// Gets the most recent transaction id.
/// </summary>
Expand All @@ -20,7 +43,7 @@ public interface IConnection
/// <summary>
/// A sequential stream of database revisions.
/// </summary>
public IObservable<IDb> Revisions { get; }
public IObservable<Revision> Revisions { get; }

/// <summary>
/// A service provider that entities can use to resolve their values
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using DynamicData;
using NexusMods.MnemonicDB.Abstractions.DatomIterators;
using NexusMods.MnemonicDB.Abstractions.Internals;
using NexusMods.Paths;
Expand Down Expand Up @@ -87,4 +88,14 @@ IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

/// <summary>
/// Create a new index segment from the given datoms
/// </summary>
public static IndexSegment From(IAttributeRegistry registry, IReadOnlyCollection<Datom> datoms)
{
using var builder = new IndexSegmentBuilder(registry, datoms.Count);
builder.Add(datoms);
return builder.Build();
}
}
29 changes: 0 additions & 29 deletions src/NexusMods.MnemonicDB.Abstractions/Models/ModelExtensions.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,43 @@
using System.Collections.Generic;
using System.Reactive.Linq;
using DynamicData;
using Microsoft.Extensions.DependencyInjection;
using NexusMods.MnemonicDB.Abstractions.DatomComparators;
using NexusMods.MnemonicDB.Abstractions.DatomIterators;
using NexusMods.MnemonicDB.Abstractions.IndexSegments;

namespace NexusMods.MnemonicDB.Abstractions.Query;

public static class MutableSlice
public static class ObservableDatoms
{

/// <summary>
/// Observe a slice of the database, as datoms are added or removed from the database, the observer will be updated
/// with the changeset of datoms that have been added or removed.
/// </summary>
public static IObservable<IChangeSet<Datom>> Observe(IConnection conn, SliceDescriptor descriptor)
public static IObservable<IChangeSet<Datom>> ObserveDatoms(this IConnection conn, SliceDescriptor descriptor)
{
var comparator = PartialComparator(descriptor.Index);
var equality = (IEqualityComparer<Datom>)comparator;
var set = new SortedSet<Datom>(comparator);

return conn.Revisions.Select((db, idx) =>
return conn.Revisions.Select((rev, idx) =>
{
if (idx == 0)
return Setup(set, db, descriptor);
return Diff(set, db, descriptor, equality);
return Setup(set, rev.Database, descriptor);
return Diff(set, rev.AddedDatoms, descriptor, equality);
});
}

private static IChangeSet<Datom> Diff(SortedSet<Datom> set, IDb db, SliceDescriptor descriptor, IEqualityComparer<Datom> comparer)
/// <summary>
/// Observe all datoms for a given entity id
/// </summary>
public static IObservable<IChangeSet<Datom>> ObserveDatoms(this IConnection conn, EntityId id)
{
return conn.ObserveDatoms(SliceDescriptor.Create(id, conn.Registry));
}

private static IChangeSet<Datom> Diff(SortedSet<Datom> set, IndexSegment updates, SliceDescriptor descriptor, IEqualityComparer<Datom> comparer)
{
var updates = db.Datoms(SliceDescriptor.Create(db.BasisTxId, db.Registry));
List<Change<Datom>>? changes = null;

foreach (var datom in updates)
Expand Down
26 changes: 19 additions & 7 deletions src/NexusMods.MnemonicDB/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class Connection : IConnection, IHostedService
private readonly ILogger<Connection> _logger;
private Task? _bootstrapTask;

private BehaviorSubject<IDb> _dbStream;
private BehaviorSubject<Revision> _dbStream;
private IDisposable? _dbStreamDisposable;

/// <summary>
Expand All @@ -39,7 +39,7 @@ public Connection(ILogger<Connection> logger, IDatomStore store, IServiceProvide
_logger = logger;
_declaredAttributes = declaredAttributes;
_store = store;
_dbStream = new BehaviorSubject<IDb>(null!);
_dbStream = new BehaviorSubject<Revision>(default!);
}

/// <inheritdoc />
Expand All @@ -50,14 +50,17 @@ public IDb Db
{
get
{
var val = _dbStream.Value;
var val = _dbStream;
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (val == null)
ThrowNullDb();
return val!;
return val!.Value.Database;
}
}

/// <inheritdoc />
public IAttributeRegistry Registry => _store.Registry;

private static void ThrowNullDb()
{
throw new InvalidOperationException("Connection not started, did you forget to start the hosted service?");
Expand All @@ -81,11 +84,11 @@ public ITransaction BeginTransaction()
}

/// <inheritdoc />
public IObservable<IDb> Revisions
public IObservable<Revision> Revisions
{
get
{
if (_dbStream == null)
if (_dbStream == default!)
ThrowNullDb();
return _dbStream!;
}
Expand Down Expand Up @@ -183,7 +186,16 @@ private async Task Bootstrap()
var storeResult = await AddMissingAttributes(_declaredAttributes);

_dbStreamDisposable = _store.TxLog
.Select(log => new Db(log.Snapshot, this, log.TxId, (AttributeRegistry)_store.Registry))
.Select(log =>
{
var db = new Db(log.Snapshot, this, log.TxId, (AttributeRegistry)_store.Registry);
var addedItems = db.Datoms(SliceDescriptor.Create(db.BasisTxId, _store.Registry));
return new Revision
{
Database = db,
AddedDatoms = addedItems
};
})
.Subscribe(_dbStream);
}
catch (Exception ex)
Expand Down
12 changes: 8 additions & 4 deletions tests/NexusMods.MnemonicDB.Tests/DbTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,9 @@ public async Task CanGetCommitUpdates()

Connection.Revisions.Subscribe(update =>
{
var datoms = update.Datoms(update.BasisTxId).ToArray();
// Only Txes we care about
if (datoms.Any(d => d.E == realId))
updates.Add(datoms);
if (update.AddedDatoms.Any(d => d.E == realId))
updates.Add(update.AddedDatoms.Select(d => d.Resolved).ToArray());
});

for (var idx = 0; idx < 4; idx++)
Expand Down Expand Up @@ -554,6 +553,8 @@ public async Task CanGetModelRevisions()
var loadoutNames = new List<string>();


// TODO: re-enable this once we decide on how to handle revisions
/*
using var subscription = loadout.Revisions()
.Select(l => l.Name)
.Finally(() => loadoutNames.Add("DONE"))
Expand All @@ -577,6 +578,9 @@ public async Task CanGetModelRevisions()
loadoutNames.Count.Should().Be(4, "All revisions should be loaded");
loadoutNames.Should().BeEquivalentTo(["Test Loadout", "Update 1", "Update 2", "DONE"]);
*/


}

[Fact]
Expand All @@ -590,7 +594,7 @@ public async Task CanObserveIndexChanges()
var slice = SliceDescriptor.Create(Mod.Name, Connection.Db.Registry);

// Setup the subscription
using var _ = MutableSlice.Observe(Connection, slice)
using var _ = ObservableDatoms.ObserveDatoms(Connection, slice)
// Snapshot the values each time
.QueryWhenChanged(datoms => datoms.Select(d => d.Resolved.ObjectValue.ToString()!).ToArray())
// Add the changes to the list
Expand Down

0 comments on commit 1b40bac

Please sign in to comment.