generated from Nexus-Mods/NexusMods.App.Template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #63 from Nexus-Mods/observable-indexes
Observable indexes
- Loading branch information
Showing
42 changed files
with
1,638 additions
and
581 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
--- | ||
hide: | ||
- toc | ||
--- | ||
|
||
## Query Design | ||
|
||
The architecture of MnemonicDB is fairly simple: tuples are stored in indexes sorted in various ways, the logging function | ||
(in `IDatomStore`) publishes a list of new databases and from those the updates in each transaction can be determined. This | ||
simple format allows for a wide variety of queries to be performed on the data and optimally a lot of performance can be gained | ||
in many parts of query. | ||
|
||
### Goals | ||
A few goals of what is desired in the query design: | ||
|
||
* **Performance**: The queries should not require O(n*m) operations as much as possible, while parts may be implemented | ||
simply and have higher complexity, options should be left in the design for optimization. | ||
* **Larger than memory**: The query results are expected to fit in memory, but the source datasets may not. This means that | ||
as much as possible only the minimal working set should be loaded into memory. | ||
* **System Sympathy**: The queries should be designed to work well the rest of the database, indexes store data pre-sorted, | ||
queries should be designed to take advantage of this. | ||
* **Live Queries**: C#'s DynamicData is a fantastic library for UI programming and is close (but not quite) to something | ||
that can be used by MnemonicDB. The queries should be designed to work well with this library, but also provide some sort | ||
of delta-update systems such as `IObservable<IChangeSet<T>>` or similar. This allows for small transactions to not require | ||
the entire query to be re-run. A delta update system fits very well with MnemonicDB's transactional publish queue, as each | ||
transaction can result in a delta of datoms added (or removed) from the database. | ||
|
||
|
||
### Concepts | ||
|
||
* **IConnection**: The connection is the primary interface for talking to the database, it can be "dereferenced" by calling | ||
`conn.Db` to get a immutable database. This interfaces also provides an `IObservable<IDb>` for subscribing to updates to the | ||
database. It also provides a `IObservable<IDb, IndexSlice>` for subscribing to updates along with the portion of the `TxLog` | ||
added in each transaction. | ||
* **IDb**: The database is a readonly view of all the data in the database as of a specific point in time. | ||
* **SliceDescriptor**: A description of a slice of an index in the database. It defines how a database value should be | ||
interpreted and which index to use. This can be thought of as a "view" on the database, consisting of a tuple of `[index, from, to]`. | ||
SliceDescriptors are immutable, and are compared by value. This means that they can be used as keys in dictionaries and sets, and makes | ||
them useful for caching. | ||
* **ObservableSlice**: A slice that can be subscribed to for updates. This is a `IObservable<IChangeSet<Datom>>` and is constructed | ||
by combining a `SliceDescriptor` and a `IConnection`. | ||
* **IndexSlice**: A loaded chunk from the database, made by combining a `SliceDescriptor` and a `IDb`. | ||
|
||
### Query Design | ||
|
||
Based on these simple primitives, a wide variety of queries can be constructed, two IndexSlices can be joined to filter each other, | ||
the datoms in the index can be grouped, sorted, and filtered in various ways. The `ObservableSlice` can be used to create live queries | ||
of the database. | ||
|
||
#### Example Queries | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
src/NexusMods.MnemonicDB.Abstractions/DatomComparators/AEVComparator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using NexusMods.MnemonicDB.Abstractions.ElementComparers; | ||
|
||
namespace NexusMods.MnemonicDB.Abstractions.DatomComparators; | ||
|
||
/// <summary> | ||
/// AEV Comparator. | ||
/// </summary> | ||
public class AEVComparator : APartialDatomComparator<AComparer, EComparer, ValueComparer>; |
50 changes: 50 additions & 0 deletions
50
src/NexusMods.MnemonicDB.Abstractions/DatomComparators/APartialDatomComparator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System; | ||
using NexusMods.MnemonicDB.Abstractions.DatomIterators; | ||
using NexusMods.MnemonicDB.Abstractions.ElementComparers; | ||
|
||
namespace NexusMods.MnemonicDB.Abstractions.DatomComparators; | ||
|
||
/// <summary> | ||
/// A comparator that only considers the EAV portion of the datom, useful for in-memory sets that | ||
/// are not concerned with time, and only contain asserts | ||
/// </summary> | ||
public abstract unsafe class APartialDatomComparator<TA, TB, TC> : IDatomComparator | ||
where TA : IElementComparer | ||
where TB : IElementComparer | ||
where TC : IElementComparer | ||
{ | ||
public static int Compare(byte* aPtr, int aLen, byte* bPtr, int bLen) | ||
{ | ||
var cmp = TA.Compare(aPtr, aLen, bPtr, bLen); | ||
if (cmp != 0) return cmp; | ||
|
||
cmp = TB.Compare(aPtr, aLen, bPtr, bLen); | ||
if (cmp != 0) return cmp; | ||
|
||
return TC.Compare(aPtr, aLen, bPtr, bLen); | ||
} | ||
|
||
/// <summary> | ||
/// Compare two datom spans | ||
/// </summary> | ||
public static int Compare(ReadOnlySpan<byte> a, ReadOnlySpan<byte> b) | ||
{ | ||
fixed(byte* aPtr = a) | ||
fixed(byte* bPtr = b) | ||
return Compare(aPtr, a.Length, bPtr, b.Length); | ||
} | ||
|
||
/// <summary> | ||
/// Compare two datoms | ||
/// </summary> | ||
public static int Compare(in Datom a, in Datom b) | ||
{ | ||
return Compare(a.RawSpan, b.RawSpan); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public int CompareInstance(byte* aPtr, int aLen, byte* bPtr, int bLen) | ||
{ | ||
return Compare(aPtr, aLen, bPtr, bLen); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/NexusMods.MnemonicDB.Abstractions/DatomComparators/AVEComparator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using NexusMods.MnemonicDB.Abstractions.ElementComparers; | ||
|
||
namespace NexusMods.MnemonicDB.Abstractions.DatomComparators; | ||
|
||
/// <summary> | ||
/// AVE Comparator. | ||
/// </summary> | ||
public class AVEComparator : APartialDatomComparator<AComparer, ValueComparer, EComparer>; |
8 changes: 8 additions & 0 deletions
8
src/NexusMods.MnemonicDB.Abstractions/DatomComparators/EAVComparator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using NexusMods.MnemonicDB.Abstractions.ElementComparers; | ||
|
||
namespace NexusMods.MnemonicDB.Abstractions.DatomComparators; | ||
|
||
/// <summary> | ||
/// EAV Comparator. | ||
/// </summary> | ||
public class EAVComparator : APartialDatomComparator<EComparer, AComparer, ValueComparer>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
src/NexusMods.MnemonicDB.Abstractions/DatomComparators/VAEComparator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using NexusMods.MnemonicDB.Abstractions.ElementComparers; | ||
|
||
namespace NexusMods.MnemonicDB.Abstractions.DatomComparators; | ||
|
||
/// <summary> | ||
/// VAE Comparator. | ||
/// </summary> | ||
public class VAEComparator : APartialDatomComparator<ValueComparer, AComparer, EComparer>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System; | ||
using System.Collections.Concurrent; | ||
using System.Linq; | ||
using System.Reactive.Linq; | ||
using System.Reactive.Subjects; | ||
using DynamicData; | ||
using NexusMods.MnemonicDB.Abstractions.Models; | ||
|
||
namespace NexusMods.MnemonicDB.Abstractions; | ||
|
||
public class DynamicCache : IDynamicCache | ||
{ | ||
public IObservable<IChangeSet<Attribute<THighLevel, TLowLevel>.ReadDatom, EntityId>> Query<TModel, THighLevel, TLowLevel>(Attribute<THighLevel, TLowLevel> attr, THighLevel value) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System.Collections.Frozen; | ||
|
||
namespace NexusMods.MnemonicDB.Abstractions; | ||
|
||
/// <summary> | ||
/// Database analytics, attached to each IDb instance but often calculated on-the fly | ||
/// and cached. | ||
/// </summary> | ||
public interface IAnalytics | ||
{ | ||
/// <summary> | ||
/// All the entities referenced in the most recent transaction of the database. | ||
/// </summary> | ||
public FrozenSet<EntityId> LatestTxIds { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.