Skip to content

Commit

Permalink
More code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
halgari committed Feb 21, 2024
1 parent 0d01177 commit fb3108f
Show file tree
Hide file tree
Showing 29 changed files with 99 additions and 93 deletions.
1 change: 1 addition & 0 deletions benchmarks/NexusMods.EventSourcing.Benchmarks/AppHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NexusMods.EventSourcing.DatomStore;
using NexusMods.EventSourcing.TestModel;
using NexusMods.Paths;

namespace NexusMods.EventSourcing.Benchmarks;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public ulong ReadFiles()
{
sum += itm.Index;
}
return (ulong)sum;
return sum;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
using BenchmarkDotNet.Attributes;
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
using NexusMods.EventSourcing.Abstractions;
using NexusMods.EventSourcing.TestModel.Model;

namespace NexusMods.EventSourcing.Benchmarks.Benchmarks;

Expand All @@ -22,17 +26,29 @@ public WriteTests()
[Benchmark]
public void AddFiles()
{
/*
var tx = _connection.BeginTransaction();
var ids = new List<EntityId>();
for (var i = 0; i < Count; i++)
{
var id = Ids.MakeId(Ids.Partition.Entity, (ulong)i);
File.Hash.Assert(tx.TempId(), (ulong)i, tx);
File.Path.Assert(tx.TempId(), $"C:\\test_{i}.txt", tx);
File.Index.Assert(tx.TempId(), (ulong)i, tx);
var file = new File(tx)
{
Hash = (ulong)i,
Path = $"C:\\test_{i}.txt",
Index = (ulong)i
};
ids.Add(file.Id);
}
var result = tx.Commit();

ids = ids.Select(id => result[id]).ToList();

var db = _connection.Db;
foreach (var id in ids)
{
var loaded = db.Get<File>(id);

loaded.Should().NotBeNull("the entity should be in the database");
}
tx.Commit();
*/
}

}
1 change: 1 addition & 0 deletions qodana.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ profile:
name: qodana.recommended
exclude:
- name: ClassNeverInstantiated.Global
- name: UnusedAutoPropertyAccessor.Global
32 changes: 29 additions & 3 deletions src/NexusMods.EventSourcing.Abstractions/Datom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace NexusMods.EventSourcing.Abstractions;

/// <summary>
/// Represents a single fact in the database. Consists of an entity, attribute, value, and transaction id.
/// </summary>
public interface IDatom
{
/// <summary>
Expand Down Expand Up @@ -34,19 +37,44 @@ public interface IDatom
void Remap(Func<EntityId, EntityId> remapFn);
}

/// <summary>
/// A datom that includes a transaction id
/// </summary>
public interface IDatomWithTx : IDatom
{
/// <summary>
/// The transaction id of the datom
/// </summary>
TxId Tx { get; }

Check notice on line 48 in src/NexusMods.EventSourcing.Abstractions/Datom.cs

View workflow job for this annotation

GitHub Actions / Qodana Community for .NET

Type member is never accessed via base type: Non-private accessibility

Only implementations of property 'Tx' are used
}


/// <summary>
/// An assertion datom, most datoms are assertions, so these are called out in a specific class
/// here to save memory
/// </summary>
/// <param name="e"></param>
/// <param name="v"></param>
/// <typeparam name="TAttr"></typeparam>
/// <typeparam name="TVal"></typeparam>
public class AssertDatom<TAttr, TVal>(ulong e, TVal v) : IDatom
where TAttr : IAttribute<TVal>
{
/// <inheritdoc />
public ulong Entity => e;

/// <summary>
/// The value of the datom
/// </summary>
public TVal V => v;

/// <inheritdoc />
public Type Attribute => typeof(TAttr);

/// <inheritdoc />
public Type ValueType => typeof(TVal);

/// <inheritdoc />
public void Emit<TSink>(ref TSink sink) where TSink : IDatomSink
{
sink.Datom<TAttr, TVal>(e, v, true);
Expand Down Expand Up @@ -77,14 +105,12 @@ public class AssertDatomWithTx<TAttr, TVal> : AssertDatom<TAttr, TVal>, IDatomWi
/// <summary>
/// Default Constructor
/// </summary>
/// <param name="e"></param>
/// <param name="v"></param>
/// <param name="tx"></param>
public AssertDatomWithTx(ulong e, TVal v, TxId tx) : base(e, v)
{
Tx = tx;
}

/// <inheritdoc />
public override string ToString()
{
return $"(assert! {Entity}, {Attribute.Namespace}/{Attribute.Name}, {V}, {Tx})";
Expand Down
8 changes: 8 additions & 0 deletions src/NexusMods.EventSourcing.Abstractions/IDatomSink.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
namespace NexusMods.EventSourcing.Abstractions;

/// <summary>
/// A sink is a typed interface that accepts the parts of a datom as values. It is generic and strongly typed
/// so that most of the data is transferred via the stack and does not require boxing. Think of all of this
/// something like IEnumerable, but as a pushed base interface instead of a pulled one.
/// </summary>
public interface IDatomSink
{
/// <summary>
/// Inject a datom into the sink.
/// </summary>
public void Datom<TAttr, TVal>(ulong e, TVal v, bool isAssert)
where TAttr : IAttribute<TVal>;
}
4 changes: 0 additions & 4 deletions src/NexusMods.EventSourcing.Abstractions/IDatomStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ public interface IDatomStore : IDisposable
/// Gets the attributeId for the given attribute. And returns an expression that reads the attribute
/// value from the expression valueSpan.
/// </summary>
/// <param name="valueSpan"></param>
/// <param name="attributeId"></param>
/// <typeparam name="TAttribute"></typeparam>
/// <returns></returns>
Expression GetValueReadExpression(Type attribute, Expression valueSpan, out ulong attributeId);

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using NexusMods.EventSourcing.Abstractions.Models;

namespace NexusMods.EventSourcing.Abstractions;

Expand Down
2 changes: 1 addition & 1 deletion src/NexusMods.EventSourcing.Abstractions/Ids.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static Partition GetPartition(ulong id)
1 => Partition.Tx,
2 => Partition.Entity,
3 => Partition.Tmp,
> 3 => Partition.Unknown,
_ => Partition.Unknown,
};
}

Expand Down
6 changes: 3 additions & 3 deletions src/NexusMods.EventSourcing.Abstractions/Symbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ private Symbol(string nsAndName)
Namespace = nsAndName[..splitOn];
}

private static readonly ConcurrentDictionary<string, Symbol> _internedSymbols = new();
private static readonly ConcurrentDictionary<string, Symbol> InternedSymbols = new();

/// <summary>
/// Construct a new symbol, or return an existing one that matches the given name
Expand All @@ -30,11 +30,11 @@ private Symbol(string nsAndName)
/// <returns></returns>
public static Symbol Intern(string nsAndName)
{
if (_internedSymbols.TryGetValue(nsAndName, out var symbol))
if (InternedSymbols.TryGetValue(nsAndName, out var symbol))
return symbol;

symbol = new Symbol(nsAndName);
return !_internedSymbols.TryAdd(nsAndName, symbol) ? _internedSymbols[nsAndName] : symbol;
return !InternedSymbols.TryAdd(nsAndName, symbol) ? InternedSymbols[nsAndName] : symbol;
}

/// <summary>
Expand Down
13 changes: 8 additions & 5 deletions src/NexusMods.EventSourcing.DatomStore/AttributeRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ public class AttributeRegistry
/// </summary>
public AttributeRegistry(IEnumerable<IValueSerializer> valueSerializers, IEnumerable<IAttribute> attributes)
{
_valueSerializersByNativeType = valueSerializers.ToDictionary(x => x.NativeType);
_valueSerializersByUniqueId = valueSerializers.ToDictionary(x => x.UniqueId);
_attributesById = attributes.ToDictionary(x => x.Id);
_attributesByType = attributes.ToDictionary(x => x.GetType());
var serializers = valueSerializers.ToArray();
_valueSerializersByNativeType = serializers.ToDictionary(x => x.NativeType);
_valueSerializersByUniqueId = serializers.ToDictionary(x => x.UniqueId);

foreach (var attr in attributes)
var attributeArray = attributes.ToArray();
_attributesById = attributeArray.ToDictionary(x => x.Id);
_attributesByType = attributeArray.ToDictionary(x => x.GetType());

foreach (var attr in attributeArray)
{
attr.SetSerializer(_valueSerializersByNativeType[attr.ValueType]);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using NexusMods.EventSourcing.Abstractions;
using NexusMods.EventSourcing.DatomStore.BuiltInSerializers;

Expand Down
2 changes: 0 additions & 2 deletions src/NexusMods.EventSourcing.DatomStore/Indexes/AETVIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@ public static unsafe int Compare(AIndexDefinition<AETVIndex> idx, KeyHeader* a,
public struct AEVTByAIterator<TAttr> : IIterator

Check warning on line 26 in src/NexusMods.EventSourcing.DatomStore/Indexes/AETVIndex.cs

View workflow job for this annotation

GitHub Actions / Qodana Community for .NET

Inconsistent Naming

Name 'AEVTByAIterator' does not match rule 'Types and namespaces'. Suggested name is 'AevtByAIterator'.
where TAttr : IAttribute
{
private readonly AETVIndex _idx;
private KeyHeader _key;
private readonly Iterator _iterator;
private readonly ulong _attrId;
private readonly AttributeRegistry _registry;

public AEVTByAIterator(ulong txId, AttributeRegistry registry, AETVIndex idx)
{
_idx = idx;
_registry = registry;
_iterator = idx.Db.NewIterator(idx.ColumnFamilyHandle);
_attrId = registry.GetAttributeId<TAttr>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public bool MaxId(Ids.Partition partition, out ulong o)
return false;
}

public unsafe struct EATVIterator : IEntityIterator, IDisposable
public unsafe struct EATVIterator : IEntityIterator

Check warning on line 58 in src/NexusMods.EventSourcing.DatomStore/Indexes/EATVIndex.cs

View workflow job for this annotation

GitHub Actions / Qodana Community for .NET

Inconsistent Naming

Name 'EATVIterator' does not match rule 'Types and namespaces'. Suggested name is 'EatvIterator'.
{
private readonly KeyHeader* _key;
private KeyHeader* _current;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Runtime.CompilerServices;
using Reloaded.Memory.Extensions;

namespace NexusMods.EventSourcing;
namespace NexusMods.EventSourcing.DatomStore;

/// <summary>
/// A IBufferWriter that uses pooled memory to reduce allocations.
Expand Down
11 changes: 3 additions & 8 deletions src/NexusMods.EventSourcing.DatomStore/RocksDBDatomStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@
using NexusMods.EventSourcing.Abstractions;
using NexusMods.EventSourcing.DatomStore.Indexes;
using RocksDbSharp;
// ReSharper disable InconsistentNaming

namespace NexusMods.EventSourcing.DatomStore;

public class RocksDBDatomStore : IDatomStore
{
private readonly object _lock = new();
private readonly ILogger<RocksDBDatomStore> _logger;
private readonly DatomStoreSettings _settings;
private readonly DbOptions _options;
private readonly RocksDb _db;
private readonly PooledMemoryBufferWriter _pooledWriter;
private readonly AttributeRegistry _registry;
Expand All @@ -26,17 +24,14 @@ public class RocksDBDatomStore : IDatomStore

public RocksDBDatomStore(ILogger<RocksDBDatomStore> logger, AttributeRegistry registry, DatomStoreSettings settings)

Check warning on line 25 in src/NexusMods.EventSourcing.DatomStore/RocksDBDatomStore.cs

View workflow job for this annotation

GitHub Actions / Qodana Community for .NET

Unused parameter: Private accessibility

Parameter 'logger' is never used
{
_settings = settings;
_logger = logger;

_registry = registry;
_registry.Populate(BuiltInAttributes.Initial);

_options = new DbOptions()
var options = new DbOptions()
.SetCreateIfMissing()
.SetCompression(Compression.Zstd);

_db = RocksDb.Open(_options, _settings.Path.ToString(), new ColumnFamilies());
_db = RocksDb.Open(options, settings.Path.ToString(), new ColumnFamilies());

_eatvIndex = new EATVIndex(_registry);
_eatvIndex.Init(_db);
Expand Down
3 changes: 0 additions & 3 deletions src/NexusMods.EventSourcing.DatomStore/Services.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ public static class Services
/// <summary>
/// Registers the event sourcing services with the service collection.
/// </summary>
/// <param name="services"></param>
/// <typeparam name="TAttribute"></typeparam>
/// <returns></returns>
public static IServiceCollection AddDatomStore(this IServiceCollection services)
{
services
Expand Down
2 changes: 1 addition & 1 deletion src/NexusMods.EventSourcing/CommitResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace NexusMods.EventSourcing;

/// <inheritdoc />
public class CommitResult(TxId newTxId, IDictionary<ulong, ulong> remaps, Connection connection, IDatom[] datoms) : ICommitResult
public class CommitResult(TxId newTxId, IDictionary<ulong, ulong> remaps, IDatom[] datoms) : ICommitResult
{
/// <inheritdoc />
public EntityId this[EntityId id] =>
Expand Down
2 changes: 1 addition & 1 deletion src/NexusMods.EventSourcing/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ EntityId RemapFn(EntityId input)
}
var newTx = _store.Transact(newDatoms);
TxId = newTx;
var result = new CommitResult(newTx, remaps, this, datomsArray);
var result = new CommitResult(newTx, remaps, datomsArray);
_updates.OnNext(result);
return result;
}
Expand Down
2 changes: 0 additions & 2 deletions src/NexusMods.EventSourcing/ModelReflector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ public void Add(TTransaction tx, IReadModel model)
/// <summary>
/// Reflects over
/// </summary>
/// <typeparam name="TReadModel"></typeparam>
/// <returns></returns>
private EmitterFn<IReadModel> CreateEmitter(Type readModel)
{
var properties = GetModelProperties(readModel);
Expand Down
3 changes: 0 additions & 3 deletions src/NexusMods.EventSourcing/Services.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ public static class Services
/// <summary>
/// Registers the event sourcing services with the service collection.
/// </summary>
/// <param name="services"></param>
/// <typeparam name="TAttribute"></typeparam>
/// <returns></returns>
public static IServiceCollection AddEventSourcing(this IServiceCollection services)
{
services.AddSingleton<IConnection, Connection>();
Expand Down
3 changes: 2 additions & 1 deletion src/NexusMods.EventSourcing/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

namespace NexusMods.EventSourcing;

public class Transaction(Connection connection) : ITransaction
/// <inheritdoc />
internal class Transaction(Connection connection) : ITransaction
{
private ulong _tempId = Ids.MinId(Ids.Partition.Tmp) + 1;
private readonly ConcurrentBag<IDatom> _datoms = new();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ namespace NexusMods.EventSourcing.DatomStore.Tests;
public abstract class ADatomStoreTest : IDisposable
{
private readonly AbsolutePath _tmpPath;
private readonly AttributeRegistry _registry;
protected readonly RocksDBDatomStore Store;

Check notice on line 11 in tests/NexusMods.EventSourcing.DatomStore.Tests/ADatomStoreTest.cs

View workflow job for this annotation

GitHub Actions / Qodana Community for .NET

Member can be made private: Non-private accessibility

Field 'Store' can be made private
protected readonly Connection Connection;

Check notice on line 12 in tests/NexusMods.EventSourcing.DatomStore.Tests/ADatomStoreTest.cs

View workflow job for this annotation

GitHub Actions / Qodana Community for .NET

Non-accessed field: Non-private accessibility

Field 'Connection' is assigned but its value is never used

Expand All @@ -19,8 +18,8 @@ protected ADatomStoreTest(IEnumerable<IValueSerializer> valueSerializers, IEnume
{
Path = _tmpPath,
};
_registry = new AttributeRegistry(valueSerializers, attributes);
Store = new RocksDBDatomStore(new NullLogger<RocksDBDatomStore>(), _registry, dbSettings);
var registry = new AttributeRegistry(valueSerializers, attributes);
Store = new RocksDBDatomStore(new NullLogger<RocksDBDatomStore>(), registry, dbSettings);
Connection = new Connection(Store, attributes, valueSerializers);
}

Expand Down
1 change: 1 addition & 0 deletions tests/NexusMods.EventSourcing.DatomStore.Tests/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using NexusMods.EventSourcing.TestModel;

namespace NexusMods.EventSourcing.DatomStore.Tests;

Expand Down
Loading

0 comments on commit fb3108f

Please sign in to comment.