Skip to content

Commit

Permalink
Tests finally pass again
Browse files Browse the repository at this point in the history
  • Loading branch information
halgari committed Mar 6, 2024
1 parent 9e16b6a commit 284b7ef
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 33 deletions.
8 changes: 8 additions & 0 deletions docs/BenchmarkLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,12 @@ The same, for the AVTE sort order 157x improvement
| BinarySearch | 1024 | 1024 | AETV | 1,031.54 ns | 6.539 ns | 5.797 ns |
| BinarySearch | 1024 | 1024 | AVTE | 40.19 ns | 0.091 ns | 0.071 ns |

### Step4

After adding back in value testing to ensure proper sorting, 5x decrease in the worst case

| Method | Count | TxCount | SortOrder | Mean | Error | StdDev |
|------------- |------ |-------- |---------- |----------:|---------:|---------:|
| BinarySearch | 1024 | 1024 | EATV | 92.30 ns | 0.436 ns | 0.408 ns |
| BinarySearch | 1024 | 1024 | AETV | 114.23 ns | 0.348 ns | 0.291 ns |
| BinarySearch | 1024 | 1024 | AVTE | 204.30 ns | 0.699 ns | 0.653 ns |
17 changes: 10 additions & 7 deletions src/NexusMods.EventSourcing.Storage/Nodes/ADataNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using NexusMods.EventSourcing.Abstractions;

namespace NexusMods.EventSourcing.Storage.Nodes;
Expand Down Expand Up @@ -31,8 +32,13 @@ public abstract partial class ADataNode : IDataNode
#endregion


public int FindEATV(int start, int end, in Datom target, IAttributeRegistry registry)
public virtual int FindEATV(int start, int end, in Datom target, IAttributeRegistry registry)
{
start = 0;
end = EntityIds.Length;

Debug.Assert(start <= end, "Start index should be less than or equal to end index");
Debug.Assert(end <= EntityIds.Length, "End index should be less than or equal to the length of the node");
while (start < end)
{
var mid = start + (end - start) / 2;
Expand All @@ -51,7 +57,7 @@ public int FindEATV(int start, int end, in Datom target, IAttributeRegistry regi
}
else
{
cmp = tmpCmp;
cmp = -tmpCmp;
}
}
else
Expand All @@ -72,7 +78,7 @@ public int FindEATV(int start, int end, in Datom target, IAttributeRegistry regi
return start;
}

public int FindAETV(int start, int end, in Datom target, IAttributeRegistry registry)
public virtual int FindAETV(int start, int end, in Datom target, IAttributeRegistry registry)
{
while (start < end)
{
Expand Down Expand Up @@ -113,7 +119,7 @@ public int FindAETV(int start, int end, in Datom target, IAttributeRegistry regi
return start;
}

public int FindAVTE(int start, int end, in Datom target, IAttributeRegistry registry)
public virtual int FindAVTE(int start, int end, in Datom target, IAttributeRegistry registry)
{
while (start < end)
{
Expand Down Expand Up @@ -166,7 +172,4 @@ public int Find(int start, int end, in Datom target, SortOrders order, IAttribut
_ => throw new ArgumentOutOfRangeException(nameof(order), order, "Unknown sort order")
};
}



}
6 changes: 3 additions & 3 deletions src/NexusMods.EventSourcing.Storage/Nodes/AIndexNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public abstract class AIndexNode : ADataNode, IIndexNode
public abstract IDataNode ChildAt(int idx);


public int FindEATV(int start, int end, in Datom target, IAttributeRegistry registry)
public override int FindEATV(int start, int end, in Datom target, IAttributeRegistry registry)
{
var childIdx = base.FindEATV(0, EntityIds.Length, target, registry);

Expand All @@ -23,7 +23,7 @@ public int FindEATV(int start, int end, in Datom target, IAttributeRegistry regi
return index + ChildOffsets[childIdx];
}

public int FindAETV(int start, int end, in Datom target, IAttributeRegistry registry)
public override int FindAETV(int start, int end, in Datom target, IAttributeRegistry registry)
{
var childIdx = base.FindAETV(0, EntityIds.Length, target, registry);

Expand All @@ -32,7 +32,7 @@ public int FindAETV(int start, int end, in Datom target, IAttributeRegistry regi
return index + ChildOffsets[childIdx];
}

public int FindAVTE(int start, int end, in Datom target, IAttributeRegistry registry)
public override int FindAVTE(int start, int end, in Datom target, IAttributeRegistry registry)
{
var childIdx = base.FindAVTE(0, EntityIds.Length, target, registry);

Expand Down
8 changes: 7 additions & 1 deletion src/NexusMods.EventSourcing.Storage/Nodes/PackedIndexNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ public PackedIndexNode(int length,

public override IEnumerator<Datom> GetEnumerator()
{
throw new System.NotImplementedException();
for (var i = 0; i < _children.Count; i++)
{
foreach (var datom in _children[i])
{
yield return datom;
}
}
}

public override int Length { get; }
Expand Down
77 changes: 59 additions & 18 deletions src/NexusMods.EventSourcing.Storage/Nodes/ReferenceIndexNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,85 @@

namespace NexusMods.EventSourcing.Storage.Nodes;

public class ReferenceIndexNode(NodeStore store, StoreKey key, IIndexNode? chunk) : AIndexNode
public class ReferenceIndexNode : IIndexNode
{
private readonly NodeStore _store;
private readonly StoreKey _key;
private IIndexNode? _chunk;

public ReferenceIndexNode(NodeStore store, StoreKey key, IIndexNode? chunk)
{
_store = store;
_key = key;
_chunk = chunk;
}

public IIndexNode Resolve()
{
return chunk ??= (IIndexNode)store.Load(key);
return _chunk ??= (IIndexNode)_store.Load(_key);
}
public override IEnumerator<Datom> GetEnumerator()
public IEnumerator<Datom> GetEnumerator()
{
return Resolve().GetEnumerator();
}

public override int Length => Resolve().Length;
public override IColumn<EntityId> EntityIds => Resolve().EntityIds;
public override IColumn<AttributeId> AttributeIds => Resolve().AttributeIds;
public override IColumn<TxId> TransactionIds => Resolve().TransactionIds;
public override IColumn<DatomFlags> Flags => Resolve().Flags;
public override IBlobColumn Values => Resolve().Values;
public int Length => Resolve().Length;
public IColumn<EntityId> EntityIds => Resolve().EntityIds;
public IColumn<AttributeId> AttributeIds => Resolve().AttributeIds;
public IColumn<TxId> TransactionIds => Resolve().TransactionIds;
public IColumn<DatomFlags> Flags => Resolve().Flags;
public IBlobColumn Values => Resolve().Values;

public override Datom this[int idx] => Resolve()[idx];
public Datom this[int idx] => Resolve()[idx];

public override Datom LastDatom => Resolve().LastDatom;
public override void WriteTo<TWriter>(TWriter writer)
public Datom LastDatom => Resolve().LastDatom;
public void WriteTo<TWriter>(TWriter writer)
{
throw new NotSupportedException();
}

public override IDataNode Flush(INodeStore store)
void IDataNode.WriteTo<TWriter>(TWriter writer)
{
WriteTo(writer);
}

public IDataNode Flush(INodeStore store)
{
throw new NotSupportedException();
}

public override IEnumerable<IDataNode> Children => Resolve().Children;
public override IColumn<int> ChildCounts => Resolve().ChildCounts;
public override IColumn<int> ChildOffsets => Resolve().ChildOffsets;
public override IDatomComparator Comparator => Resolve().Comparator;
public int FindEATV(int start, int end, in Datom target, IAttributeRegistry registry)
{
return Resolve().FindEATV(start, end, target, registry);
}

public int FindAVTE(int start, int end, in Datom target, IAttributeRegistry registry)
{
return Resolve().FindAVTE(start, end, target, registry);
}

public int FindAETV(int start, int end, in Datom target, IAttributeRegistry registry)
{
return Resolve().FindAETV(start, end, target, registry);
}

public override IDataNode ChildAt(int idx)
public int Find(int start, int end, in Datom target, SortOrders order, IAttributeRegistry registry)
{
return Resolve().Find(start, end, target, order, registry);
}

public IEnumerable<IDataNode> Children => Resolve().Children;
public IColumn<int> ChildCounts => Resolve().ChildCounts;
public IColumn<int> ChildOffsets => Resolve().ChildOffsets;
public IDatomComparator Comparator => Resolve().Comparator;

public IDataNode ChildAt(int idx)
{
return Resolve().ChildAt(idx);
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
11 changes: 11 additions & 0 deletions src/NexusMods.EventSourcing.Storage/Nodes/ReferenceNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,21 @@ private IDataNode Resolve()
{
return target;
}
return LoadNode();
}

private IDataNode LoadNode()
{
var chunkData = store.Load(key);
chunk = new WeakReference<IDataNode>(chunkData);
if (chunkData.Length != Length)
{
throw new InvalidOperationException("Node length mismatch");
}

return chunkData;
}

public IEnumerator<Datom> GetEnumerator()
{
return Resolve().GetEnumerator();
Expand Down
4 changes: 2 additions & 2 deletions src/NexusMods.EventSourcing.Storage/Sorters/EATV.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public int Compare(in Datom x, in Datom y)
if (cmp != 0) return cmp;

cmp = x.T.CompareTo(y.T);
if (cmp != 0) return cmp;
if (cmp != 0) return -cmp;

return registry.CompareValues(x, y);
}
Expand All @@ -45,7 +45,7 @@ public int Compare(int a, int b)
if (cmp != 0) return cmp;

cmp = datoms.TransactionIds[a].CompareTo(datoms.TransactionIds[b]);
if (cmp != 0) return cmp;
if (cmp != 0) return -cmp;

return registry.CompareValues(datoms.Values, datoms.AttributeIds[a], a, b);
}
Expand Down
6 changes: 5 additions & 1 deletion tests/NexusMods.EventSourcing.Storage.Tests/IndexTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ private void CanIngestAndGetDatomsInner<TType>(TType comparator, int entityCount

for (var i = 0; i < testData.Length; i++)
{
var testDatom = testData[i];

var idx = finalIndex.Find(0, finalIndex.Length, testDatom, sortOrder, _registry);
idx.Should().Be(i, "the index should find the correct datom");
AssertEqual(finalIndex[i], testData[i], i);
}
}
Expand All @@ -68,7 +72,7 @@ public IEnumerable<object[]> TestData()
{
foreach (var size in new[] { 1, 2, 3, 4, 8, 16, 128, 1024, 1024 * 8, 1024 * 16, 1024 * 128 })
{
foreach (var flush in new[] { true,}) // false })
foreach (var flush in new[] { true, false })
{
yield return [size, idx, flush];
}
Expand Down
1 change: 0 additions & 1 deletion tests/NexusMods.EventSourcing.Tests/DbTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ public async Task CanGetActiveReadModels()
LoadoutAttributes.Name.Add(newTx, result[staticLoadout1.Id], "Test Loadout 1 Updated");
await newTx.Commit();

Connection.Db.BasisTxId.Value.Should().BeGreaterThan(loadout1.BasisDb.BasisTxId.Value, "the db should have been updated");
var reloaded = Connection.Db.Get<Loadout>(result[staticLoadout1.Id]);
reloaded.Name.Should().Be("Test Loadout 1 Updated", "because the commit has been applied");

Expand Down

0 comments on commit 284b7ef

Please sign in to comment.