Skip to content

Repository files navigation

Lightning.NET

.NET TestsNuGet version

Lightning.NET is a .NET library that provides a fast and easy-to-use interface to the Lightning Memory-Mapped Database (LMDB), a high-performance key-value store. This library enables .NET developers to leverage LMDB's efficiency and reliability in their applications.

Features

  • High Performance: Direct interaction with LMDB ensures minimal overhead (no copies / 0-alloc when using Span) and maximum speed.
  • Simplicity: The API is designed to be straightforward, making it easy to integrate into existing projects.
  • Flexibility: Supports various database configurations, including handling multiple values for the same key.
  • Reliable: It is fully transactional with complete ACID semantics.

Installation

Lightning.NET is available as a NuGet package. To install it, run the following command in the Package Manager Console:

Install-Package LightningDB

Alternatively, you can install it via the .NET CLI:

dotnet add package LightningDB

Basic Usage

Here's a simple example demonstrating how to create an environment, open a database, and perform basic put and get operations:

usingSystem;usingSystem.Text;usingLightningDB;classProgram{staticvoidMain(){// Specify the path to the database environmentusingvarenv=newLightningEnvironment("path_to_your_database");env.Open();// Begin a transaction and open (or create) a databaseusing(vartx=env.BeginTransaction())using(vardb=tx.OpenDatabase(configuration:newDatabaseConfiguration{Flags=DatabaseOpenFlags.Create})){// Put a key-value pair into the databasetx.Put(db,UTF8.GetBytes("hello"),UTF8.GetBytes("world"));tx.Commit();}// Begin a read-only transaction to retrieve the valueusing(vartx=env.BeginTransaction(TransactionBeginFlags.ReadOnly))using(vardb=tx.OpenDatabase()){var(resultCode,key,value)=tx.Get(db,Encoding.UTF8.GetBytes("hello"));if(resultCode==MDBResultCode.Success){Console.WriteLine($"{UTF8.GetString(key)}: {UTF8.GetString(value)}");}else{Console.WriteLine("Key not found.");}}}}

In this example:

  • We create a new LMDB environment at the specified path.
  • We open a database within a transaction, inserting the key-value pair ("hello", "world").
  • We commit the transaction to save the changes.
  • We then start a read-only transaction to retrieve and display the value associated with the key "hello".

Handling Multiple Values for the Same Key

LMDB supports storing multiple values for a single key when the database is configured with the Dupsort flag. Here's how you can work with duplicate keys and use the cursor's NextDuplicate function:

usingSystem;usingSystem.Text;usingLightningDB;classProgram{staticvoidMain(){usingvarenv=newLightningEnvironment("path_to_your_database");env.Open();// Configure the database to support duplicate keysvardbConfig=newDatabaseConfiguration{Flags=DatabaseOpenFlags.Create|DatabaseOpenFlags.DuplicatesSort};// Begin a transaction and open the databaseusing(vartx=env.BeginTransaction())using(vardb=tx.OpenDatabase(configuration:dbConfig)){varkey=Encoding.UTF8.GetBytes("fruit");varvalue1=Encoding.UTF8.GetBytes("apple");varvalue2=Encoding.UTF8.GetBytes("cherry");varvalue3=Encoding.UTF8.GetBytes("banana");// Insert multiple values for the same keytx.Put(db,key,value1);tx.Put(db,key,value2);tx.Put(db,key,value3);tx.Commit();}// Begin a read-only transaction to retrieve the valuesusing(vartx=env.BeginTransaction(TransactionBeginFlags.ReadOnly))using(vardb=tx.OpenDatabase())using(varcursor=tx.CreateCursor(db)){varkey=Encoding.UTF8.GetBytes("fruit");// Position the cursor at the first occurrence of the keyvarresult=cursor.Set(key);if(result==MDBResultCode.Success){do{varcurrent=cursor.GetCurrent();varcurrentKey=current.key.AsSpan();varcurrentValue=current.value.AsSpan();Console.WriteLine($"{UTF8.GetString(currentKey)}: {UTF8.GetString(currentValue)}");}// Move to the next duplicate valuewhile(cursor.NextDuplicate().resultCode==MDBResultCode.Success);}else{Console.WriteLine("Key not found.");}//Or even simplervarvalues=cursor.AllValuesFor(key);foreach(varvalueinvalues){Console.WriteLine($"fruit: {Encoding.UTF8.GetString(value.AsSpan())}");}}}}

In this example:

  • We configure the database with the DupSort flag to allow multiple values for a single key.
  • We insert three different values ("apple", "cherry", "banana") under the same key "fruit".
  • Using a cursor, we iterate over all values associated with the key "fruit" by moving to the next duplicate entry and see the values retrieved are ordered.
  • Then we demonstrate doing the same thing with IEnumerable instead.

Custom Key Ordering

LightningDB provides built-in, allocation-free comparers for custom key sorting and duplicate ordering. Use them with CompareWith() for keys or FindDuplicatesWith() for duplicate values:

varconfig=newDatabaseConfiguration{Flags=DatabaseOpenFlags.Create|DatabaseOpenFlags.DuplicatesSort};// Sort keys as signed integers (negative values sort before positive)config.CompareWith(SignedIntegerComparer.Instance);// Sort duplicate values in reverse orderconfig.FindDuplicatesWith(ReverseBitwiseComparer.Instance);usingvardb=tx.OpenDatabase(configuration:config);

Available comparers in LightningDB.Comparers:

ComparerDescription
BitwiseComparerLexicographic byte comparison (default LMDB behavior)
ReverseBitwiseComparerLexicographic descending
SignedIntegerComparer4/8-byte signed integers with proper negative ordering
UnsignedIntegerComparer4/8-byte unsigned integers
Utf8StringComparerOrdinal UTF-8 string comparison
LengthComparerSort by length first, then content
LengthOnlyComparerSort by length only
HashCodeComparerHash-based comparison for large values

Reverse variants are available for most comparers (e.g., ReverseSignedIntegerComparer).

Additional Resources

For more detailed examples and advanced usage, refer to the unit tests in the Lightning.NET repository.

The Official LMDB API documentation is also a valuable resource for understanding the underlying database engine.

About

.NET library for LMDB key-value store

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages