Skip to content

Commit

Permalink
Merge pull request #89 from Nexus-Mods/observeall
Browse files Browse the repository at this point in the history
Add `ObserveAll` tests and benchmarks
  • Loading branch information
halgari authored Aug 15, 2024
2 parents d35b2c0 + d6d20d4 commit f371586
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Engines;
using NexusMods.MnemonicDB.Abstractions.TxFunctions;
using NexusMods.MnemonicDB.TestModel;

namespace NexusMods.MnemonicDB.Benchmarks.Benchmarks;

[MemoryDiagnoser]
[SimpleJob(runStrategy: RunStrategy.Monitoring, warmupCount: 1)]
public class ObserveAllBenchmarks : ABenchmark
{
private string[] _names = [];

[Params(100, 1_000, 10_000)]
public int N { get; set; }

[GlobalSetup]
public async ValueTask GlobalSetup()
{
await InitializeAsync();
_names = Enumerable.Range(start: 0, count: N).Select(i => $"Loadout {i}").ToArray();
}

[IterationCleanup]
public void IterationCleanup()
{
using var tx = Connection.BeginTransaction();

foreach (var entity in Loadout.All(Connection.Db))
{
tx.Delete(entity, recursive: false);
}

tx.Commit().GetAwaiter().GetResult();
}

[Benchmark]
public async ValueTask ObserveAll()
{
using var disposable = Loadout.ObserveAll(Connection).Subscribe(_ => { });

using var tx = Connection.BeginTransaction();

foreach (var name in _names)
{
_ = new Loadout.New(tx)
{
Name = name,
};
}

await tx.Commit();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
+ | 0200000000000001 | (0015) Hash | 0x00000000DEADBEEF | 0100000000000002
+ | 0200000000000003 | (0018) Name | Test Mod 1 | 0100000000000002
+ | 0200000000000005 | (0018) Name | Test Mod 2 | 0100000000000002
+ | 0200000000000004 | (001A) Name | Test Loadout 1 | 0100000000000002
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
+ | 0200000000000001 | (0015) Hash | 0x00000000DEADBEEF | 0100000000000002
+ | 0200000000000003 | (0018) Name | Test Mod 1 | 0100000000000002
+ | 0200000000000005 | (0018) Name | Test Mod 2 | 0100000000000002
+ | 0200000000000004 | (001A) Name | Test Loadout 1 | 0100000000000002
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
+ | 0200000000000001 | (0015) Hash | 0x00000000DEADBEEF | 0100000000000002
+ | 0200000000000003 | (0018) Name | Test Mod 1 | 0100000000000002
+ | 0200000000000005 | (0018) Name | Test Mod 2 | 0100000000000002
+ | 0200000000000004 | (001A) Name | Test Loadout 1 | 0100000000000002
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
+ | 0200000000000001 | (0015) Hash | 0x00000000DEADBEEF | 0100000000000002
+ | 0200000000000003 | (0018) Name | Test Mod 1 | 0100000000000002
+ | 0200000000000005 | (0018) Name | Test Mod 2 | 0100000000000002
+ | 0200000000000004 | (001A) Name | Test Loadout 1 | 0100000000000002
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
+ | 0200000000000001 | (0015) Hash | 0x00000000DEADBEEF | 0100000000000002
+ | 0200000000000003 | (0018) Name | Test Mod 1 | 0100000000000002
+ | 0200000000000005 | (0018) Name | Test Mod 2 | 0100000000000002
+ | 0200000000000004 | (001A) Name | Test Loadout 1 | 0100000000000002
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
+ | 0200000000000001 | (0015) Hash | 0x00000000DEADBEEF | 0100000000000002
+ | 0200000000000003 | (0018) Name | Test Mod 1 | 0100000000000002
+ | 0200000000000005 | (0018) Name | Test Mod 2 | 0100000000000002
+ | 0200000000000004 | (001A) Name | Test Loadout 1 | 0100000000000002
5 changes: 2 additions & 3 deletions tests/NexusMods.MnemonicDB.TestModel/Loadout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ namespace NexusMods.MnemonicDB.TestModel;
public partial class Loadout : IModelDefinition
{
private const string Namespace = "NexusMods.MnemonicDB.TestModel.Loadout";
public static readonly StringAttribute Name = new(Namespace, nameof(Name));
public static readonly StringAttribute Name = new(Namespace, nameof(Name)) { IsIndexed = true };
public static readonly BackReferenceAttribute<Mod> Mods = new(Mod.Loadout);
public static readonly BackReferenceAttribute<Collection> Collections = new(Collection.Loadout);
public static readonly AbsolutePathAttribute GamePath = new(Namespace, nameof(GamePath))
{ IsOptional = true };
public static readonly AbsolutePathAttribute GamePath = new(Namespace, nameof(GamePath)) { IsOptional = true };
}
97 changes: 97 additions & 0 deletions tests/NexusMods.MnemonicDB.Tests/ObservableTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using DynamicData;
using NexusMods.MnemonicDB.Abstractions.TxFunctions;
using NexusMods.MnemonicDB.TestModel;

namespace NexusMods.MnemonicDB.Tests;

public class ObservableTests : AMnemonicDBTest
{
public ObservableTests(IServiceProvider provider) : base(provider) { }

[Fact]
public async Task TestObserveAll()
{
using var disposable = Loadout
.ObserveAll(Connection)
.Transform(loadout => loadout.Name)
.Bind(out var list)
.Subscribe();

list.Should().BeEmpty();

await Add("Loadout 1");

list.Should().ContainSingle(static name => name.Equals("Loadout 1"));

await Add("Loadout 2");

list.Should().HaveCount(2).And.ContainInOrder(["Loadout 1", "Loadout 2"]);

await Add("Loadout 3", "Loadout 4");

list.Should().HaveCount(4).And.ContainInOrder(["Loadout 1", "Loadout 2", "Loadout 3", "Loadout 4"]);

await Delete("Loadout 2");

list.Should().HaveCount(3).And.ContainInOrder(["Loadout 1", "Loadout 3", "Loadout 4"]);

await Delete("Loadout 1", "Loadout 4");

list.Should().ContainSingle(static name => name.Equals("Loadout 3"));

await Delete("Loadout 3");

list.Should().BeEmpty();
}

[Fact]
public async Task StressTest()
{
using var disposable = Loadout
.ObserveAll(Connection)
.Transform(loadout => loadout.Name)
.Bind(out var list)
.Subscribe();

var stress = Enumerable.Range(start: 0, count: 100).Select(i => $"Loadout {i}").ToArray();
await Add(stress);

list.Should().ContainInOrder(stress);

await Delete(stress);

list.Should().BeEmpty();
}

private async ValueTask Add(params string[] names)
{
using var tx = Connection.BeginTransaction();

foreach (var name in names)
{
_ = new Loadout.New(tx)
{
Name = name,
};
}


await tx.Commit();
}

private async ValueTask Delete(params string[] names)
{
var db = Connection.Db;
using var tx = Connection.BeginTransaction();

foreach (var name in names)
{
var entities = Loadout.FindByName(db, name);
entities.Should().ContainSingle();

tx.Delete(entities.First(), recursive: false);
}

await tx.Commit();
}
}

0 comments on commit f371586

Please sign in to comment.