Skip to content

Commit

Permalink
Merge pull request #118 from Nexus-Mods/ro-rocksdb-mode
Browse files Browse the repository at this point in the history
Add readonly helpers, compaction, and zstd compression
  • Loading branch information
halgari authored Jan 21, 2025
2 parents 1c09025 + aab3c0c commit 0f9d026
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Changelog

### 0.9.99 - 21/1/2025
* Provide a way to open a RocksDB backend in read-only mode
* Default to zstd compression for RocksDB vs the previous snappy compression
* Provide a `FlushAndCompact` method on the connection so that the user can manually trigger a compaction of the database

### 0.9.98 - 16/1/2025
* Massively improve performance of the `ObserveDatoms` function. It is now ~200x faster than the previous version
* Clean up the logging in the inner transacting loop, switch to high performance logging for those few critical messages
Expand Down
5 changes: 5 additions & 0 deletions src/NexusMods.MnemonicDB.Abstractions/IConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ public interface IConnection
/// of datoms that were excised.
/// </summary>
public Task<ICommitResult> Excise(EntityId[] entityIds);

/// <summary>
/// Flushes the in-memory transaction log to the database, and compacts the database to remove any unused space.
/// </summary>
public Task<ICommitResult> FlushAndCompact();

/// <summary>
/// Update the database's schema with the given attributes.
Expand Down
8 changes: 8 additions & 0 deletions src/NexusMods.MnemonicDB/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,14 @@ public async Task<ICommitResult> Excise(EntityId[] entityIds)
return await tx.Commit();
}

/// <inheritdoc />
public async Task<ICommitResult> FlushAndCompact()
{
var tx = new Transaction(this);
tx.Set(new FlushAndCompact());
return await tx.Commit();
}

/// <inheritdoc />
public Task UpdateSchema(params IAttribute[] attribute)
{
Expand Down
14 changes: 14 additions & 0 deletions src/NexusMods.MnemonicDB/InternalTxFunctions/FlushAndCompact.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using NexusMods.MnemonicDB.Storage;

namespace NexusMods.MnemonicDB.InternalTxFunctions;

/// <summary>
/// Performs a flush and compact operation on the backend.
/// </summary>
internal class FlushAndCompact : AInternalFn
{
public override void Execute(DatomStore store)
{
store.Backend.FlushAndCompact();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,10 @@ public interface IStoreBackend : IDisposable
/// during calls to GetIterator
/// </summary>
public ISnapshot GetSnapshot();


/// <summary>
/// Flushes all the logs to disk, and performs a compaction, recommended if you want to archive the database
/// and move it somewhere else.
/// </summary>
public void FlushAndCompact();
}
6 changes: 6 additions & 0 deletions src/NexusMods.MnemonicDB/Storage/InMemoryBackend/Backend.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ public ISnapshot GetSnapshot()
return new Snapshot(_index, AttributeCache);
}

/// <inheritdoc />
public void FlushAndCompact()
{
// No need to do anything
}

/// <inheritdoc />
public void Dispose() { }
}
23 changes: 20 additions & 3 deletions src/NexusMods.MnemonicDB/Storage/RocksDbBackend/Backend.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ public class Backend : IStoreBackend
{
internal RocksDb? Db = null!;
private IntPtr _comparator;
private readonly bool _isReadOnly;

/// <summary>
/// Default constructor
/// </summary>
public Backend()
public Backend(bool readOnly = false)
{
_isReadOnly = readOnly;
AttributeCache = new AttributeCache();
}

Expand Down Expand Up @@ -50,10 +52,25 @@ public void Init(AbsolutePath location)
var options = new DbOptions()
.SetCreateIfMissing()
.SetCreateMissingColumnFamilies()
.SetCompression(Compression.Lz4)
.SetCompression(Compression.Zstd)
.SetComparator(_comparator);

Db = RocksDb.Open(options, location.ToString());
Native.Instance.rocksdb_options_set_bottommost_compression(options.Handle, (int)Compression.Zstd);

if (_isReadOnly)
Db = RocksDb.OpenReadOnly(options, location.ToString(), false);
else
Db = RocksDb.Open(options, location.ToString());
}

/// <summary>
/// Flushes all the logs to disk, and performs a compaction, recommended if you want to archive the database
/// and move it somewhere else.
/// </summary>
public void FlushAndCompact()
{
Db?.Flush(new FlushOptions().SetWaitForFlush(true));
Db?.CompactRange([0x00], [0xFF]);
}

/// <inheritdoc />
Expand Down
5 changes: 5 additions & 0 deletions tests/NexusMods.MnemonicDB.Storage.Tests/NullConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ public Task<ICommitResult> Excise(EntityId[] entityIds)
throw new NotSupportedException();
}

public Task<ICommitResult> FlushAndCompact()
{
throw new NotSupportedException();
}

public Task UpdateSchema(params IAttribute[] attribute)
{
throw new NotSupportedException();
Expand Down
19 changes: 19 additions & 0 deletions tests/NexusMods.MnemonicDB.Tests/DbTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1233,4 +1233,23 @@ public async Task CanHandleLargeNumbersOfSubscribers()
sub.Dispose();
}
}

[Fact]
public async Task CanFlushAndCompactTheDB()
{
var tx = Connection.BeginTransaction();

for (int i = 0; i < 1000; i++)
{
_ = new Mod.New(tx)
{
Name = "Test Mod " + i,
Source = new Uri("http://test.com"),
LoadoutId = EntityId.From(0)
};
}
await tx.Commit();

await Connection.FlushAndCompact();
}
}

0 comments on commit 0f9d026

Please sign in to comment.