Wrapped Dynamic IL generation with debugging + extensions
IOC Container (SourceGenerator based)
Object Database with Relations
Snappy Compression
Event Storage
Bon (Binary object notation)
Incremental SourceGenerator for IOC Container factory generation
All code written in C# 11 and licensed under very permissive MIT license. Targeting .Net 8.0, main code has just 1 dependency (Microsoft.Extensions.Primitives). Code is tested using xUnit Framework. Used in production on Windows and Linux, on MacOS works as well.
Please is you find it useful or have questions, write me e-mail boris.letocha@gmail.com so I know that it is used.
It is available in Nuget http://www.nuget.org/packages/BTDB. Source code drops are Github releases.
Key Value Database
Features
This is Key Value store written in C# with 2 implementation old on managed heap and new on native heap (has also prefix compression).
using (var fileCollection = new InMemoryFileCollection())
using (IKeyValueDB db = new KeyValueDB(fileCollection))
{
using (var tr = db.StartTransaction())
{
tr.CreateOrUpdateKeyValue(new byte[] { 1 }, new byte[100000]);
tr.Commit();
}
}
Roadmap
Everything is there just use it
Wrapped Dynamic IL generation with debugging + extensions
This help you to write fluent code which generates IL code in runtime. It is used in Object Database part.
Sample code
var method = ILBuilder.Instance.NewMethod<Func<Nested>>("SampleCall");
var il = method.Generator;
var local = il.DeclareLocal(typeof(Nested), "n");
il
.Newobj(() => new Nested())
.Dup()
.Stloc(local)
.Ldstr("Test")
.Call(() => ((Nested)null).Fun(""))
.Ldloc(local)
.Ret();
var action = method.Create();
Roadmap
Add support for all IL instructions as needed
Deprecate this by replacing its usages by Source Generator
Object Database
Features
Builds on top of Key Value Database and Reflection.Emit extensions.
It stores Plain .Net Objects and only their public properties with getters and setters.
All ACID and MVCC properties are preserved of course.
Automatic upgrading of model on read with dynamically generated optimal IL code.
Automatic versioning of model changes.
Enumeration of all objects
Each object type could store its "singleton" - very useful for root objects
Relations - Table with primary key and multiple secondary keys
By default objects are stored inline in parent object, use IIndirect for objects with Oid which will load lazily
public class Person
{
public string Name { get; set; }
public uint Age { get; set; }
}
using (var tr = _db.StartTransaction())
{
tr.Store(new Person { Name = "Bobris", Age = 35 });
tr.Commit();
}
using (var tr = _db.StartTransaction())
{
var p = tr.Enumerate<Person>().First();
Assert.AreEqual("Bobris", p.Name);
Assert.AreEqual(35, p.Age);
}
Roadmap
Support more types of properties
Free text search (far future if ever)
Event storage
Features
Optimal serialization with metadata
Deserialization also to dynamic
Storage is transactional
As storage could be used Azure Page Blobs
EventStorage2 is specialized to be used with Kafka, metadata are stored in separate topic
Bon
Bon Binary object notation is allows creating and reading JavaScript/C# values with extensions like Dictionary/Map into binary notation. It is much faster to parse, write, skip, search by keys than JSON, size will be also smaller in most cases, in some cases much more smaller.