-
Notifications
You must be signed in to change notification settings - Fork 90
Expand file tree
/
Copy pathDatabaseConfiguration.cs
More file actions
102 lines (88 loc) · 3.2 KB
/
DatabaseConfiguration.cs
File metadata and controls
102 lines (88 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using LightningDB.Native;
using static LightningDB.Native.Lmdb;
namespace LightningDB;
/// <summary>
/// Represents the configuration for a database in the LightningDB library.
/// Allows setting custom flags and configuring comparer logic for database operations.
/// </summary>
public class DatabaseConfiguration
{
private IComparer<MDBValue>? _comparer;
private IComparer<MDBValue>? _duplicatesComparer;
public DatabaseConfiguration()
{
Flags = DatabaseOpenFlags.None;
}
/// <summary>
/// Gets or sets the configuration flags used when opening a database.
/// </summary>
/// <remarks>
/// The <see cref="Flags"/> property specifies the behavior of the database based on the combination of
/// values from the <see cref="DatabaseOpenFlags"/> enumeration. These flags determine how the database
/// should be opened and interacted with, such as creating new databases, sorting duplicates, or using
/// integer keys. The default value is <see cref="DatabaseOpenFlags.None"/>.
/// </remarks>
public DatabaseOpenFlags Flags { get; set; }
internal IDisposable ConfigureDatabase(LightningTransaction tx, LightningDatabase db)
{
var pinnedComparer = new ComparerKeepAlive();
if (_comparer != null)
{
CompareFunction compare = Compare;
pinnedComparer.AddComparer(compare);
mdb_set_compare(tx._handle, db._handle, compare);
}
if (_duplicatesComparer == null) return pinnedComparer;
CompareFunction dupCompare = IsDuplicate;
pinnedComparer.AddComparer(dupCompare);
mdb_set_dupsort(tx._handle, db._handle, dupCompare);
return pinnedComparer;
}
private int Compare(ref MDBValue left, ref MDBValue right)
{
return _comparer!.Compare(left, right);
}
private int IsDuplicate(ref MDBValue left, ref MDBValue right)
{
return _duplicatesComparer!.Compare(left, right);
}
/// <summary>
/// Sets a custom comparer for database operations using the specified comparer.
/// </summary>
/// <param name="comparer">
/// The comparer implementation to use for comparing MDBValue objects.
/// </param>
public void CompareWith(IComparer<MDBValue> comparer)
{
_comparer = comparer;
}
/// <summary>
/// Sets a custom comparer for detecting duplicate records in the database.
/// </summary>
/// <param name="comparer">
/// The comparer implementation to use for identifying duplicates between MDBValue objects.
/// </param>
public void FindDuplicatesWith(IComparer<MDBValue> comparer)
{
_duplicatesComparer = comparer;
}
private class ComparerKeepAlive : IDisposable
{
private readonly List<GCHandle> _comparisons = new();
public void AddComparer(CompareFunction compare)
{
var handle = GCHandle.Alloc(compare);
_comparisons.Add(handle);
}
public void Dispose()
{
for (var i = 0; i < _comparisons.Count; ++i)
{
_comparisons[i].Free();
}
}
}
}