|
5 | 5 | using System.Runtime.InteropServices; |
6 | 6 | using System.Text; |
7 | 7 | using System.Threading.Tasks; |
| 8 | +using Transitional; |
8 | 9 |
|
9 | 10 | namespace RocksDbSharp |
10 | 11 | { |
11 | 12 | public class ColumnFamilyOptions : OptionsHandle |
12 | 13 | { |
13 | | - Comparator Comparator { get; set; } |
14 | | - IntPtr ComparatorStatePtr { get; set; } |
| 14 | + ComparatorReferences ComparatorRef { get; set; } |
15 | 15 |
|
16 | 16 | public ColumnFamilyOptions SetBlockBasedTableFactory(BlockBasedTableOptions table_options) |
17 | 17 | { |
@@ -169,51 +169,72 @@ public ColumnFamilyOptions SetComparator(IntPtr comparator) |
169 | 169 | /// </summary> |
170 | 170 | public ColumnFamilyOptions SetComparator(Comparator comparator) |
171 | 171 | { |
172 | | - // Hold onto the reference to the comparator |
173 | | - Comparator = comparator; |
174 | | - |
175 | 172 | // Allocate some memory for the name bytes |
176 | 173 | var name = comparator.Name ?? comparator.GetType().FullName; |
177 | 174 | var nameBytes = Encoding.UTF8.GetBytes(name + "\0"); |
178 | 175 | var namePtr = Marshal.AllocHGlobal(nameBytes.Length); |
179 | 176 | Marshal.Copy(nameBytes, 0, namePtr, nameBytes.Length); |
180 | 177 |
|
| 178 | + // Hold onto a reference to everything that needs to stay alive |
| 179 | + ComparatorRef = new ComparatorReferences |
| 180 | + { |
| 181 | + GetComparator = () => comparator, |
| 182 | + CompareDelegate = Comparator_Compare, |
| 183 | + DestructorDelegate = Comparator_Destroy, |
| 184 | + NameDelegate = Comparator_GetNamePtr, |
| 185 | + }; |
| 186 | + |
181 | 187 | // Allocate the state |
182 | 188 | var state = new ComparatorState |
183 | 189 | { |
184 | 190 | NamePtr = namePtr, |
| 191 | + GetComparatorPtr = CurrentFramework.GetFunctionPointerForDelegate<GetComparator>(ComparatorRef.GetComparator) |
185 | 192 | }; |
186 | 193 | var statePtr = Marshal.AllocHGlobal(Marshal.SizeOf(state)); |
187 | 194 | Marshal.StructureToPtr(state, statePtr, false); |
188 | 195 |
|
189 | 196 | // Create the comparator |
190 | 197 | IntPtr handle = Native.Instance.rocksdb_comparator_create( |
191 | 198 | state: statePtr, |
192 | | - destructor: Comparator_Destroy, |
193 | | - compare: Comparator_Compare, |
194 | | - name: Comparator_GetNamePtr |
| 199 | + destructor: ComparatorRef.DestructorDelegate, |
| 200 | + compare: ComparatorRef.CompareDelegate, |
| 201 | + name: ComparatorRef.NameDelegate |
195 | 202 | ); |
196 | 203 |
|
197 | | - ComparatorStatePtr = statePtr; |
198 | | - |
199 | 204 | return SetComparator(handle); |
200 | 205 | } |
201 | 206 |
|
| 207 | + delegate Comparator GetComparator(); |
| 208 | + private class ComparatorReferences |
| 209 | + { |
| 210 | + public GetComparator GetComparator { get; set; } |
| 211 | + public DestructorDelegate DestructorDelegate { get; set; } |
| 212 | + public CompareDelegate CompareDelegate { get; set; } |
| 213 | + public NameDelegate NameDelegate { get; set; } |
| 214 | + } |
| 215 | + |
202 | 216 | private unsafe int Comparator_Compare(IntPtr state, IntPtr a, UIntPtr alen, IntPtr b, UIntPtr blen) |
203 | | - => Comparator.Compare(a, alen, b, blen); |
| 217 | + { |
| 218 | + var getComparatorPtr = (*((ComparatorState*)state)).GetComparatorPtr; |
| 219 | + var getComparator = CurrentFramework.GetDelegateForFunctionPointer<GetComparator>(getComparatorPtr); |
| 220 | + var comparator = getComparator(); |
| 221 | + return comparator.Compare(a, alen, b, blen); |
| 222 | + } |
204 | 223 |
|
205 | | - private unsafe void Comparator_Destroy(IntPtr state) |
| 224 | + private unsafe static void Comparator_Destroy(IntPtr state) |
206 | 225 | { |
207 | 226 | var namePtr = (*((ComparatorState*)state)).NamePtr; |
208 | 227 | Marshal.FreeHGlobal(namePtr); |
209 | 228 | Marshal.FreeHGlobal(state); |
210 | 229 | } |
211 | | - private unsafe IntPtr Comparator_GetNamePtr(IntPtr state) |
| 230 | + |
| 231 | + private unsafe static IntPtr Comparator_GetNamePtr(IntPtr state) |
212 | 232 | => (*((ComparatorState*)state)).NamePtr; |
213 | 233 |
|
214 | 234 | [StructLayout(LayoutKind.Sequential)] |
215 | 235 | private struct ComparatorState |
216 | 236 | { |
| 237 | + public IntPtr GetComparatorPtr { get; set; } |
217 | 238 | public IntPtr NamePtr { get; set; } |
218 | 239 | } |
219 | 240 |
|
|
0 commit comments