Skip to content

Commit a445604

Browse files
committed
Use CursorManager to release cursors
Instead of Closing event
1 parent 98cc231 commit a445604

File tree

6 files changed

+96
-91
lines changed

6 files changed

+96
-91
lines changed

src/LightningDB/Factories/CursorManager.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,65 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Text;
5+
using LightningDB.Native;
56

67
namespace LightningDB.Factories
78
{
89
class CursorManager
910
{
11+
private readonly LightningTransaction _transaction;
12+
13+
private readonly HashSet<IntPtr> _cursors;
14+
15+
public CursorManager(LightningTransaction transaction)
16+
{
17+
if (transaction == null)
18+
throw new ArgumentNullException("transaction");
19+
20+
_transaction = transaction;
21+
22+
_cursors = new HashSet<IntPtr>();
23+
}
24+
25+
private IntPtr CreateCursorHandle(uint dbHandle)
26+
{
27+
var handle = default(IntPtr);
28+
NativeMethods.Execute(lib => lib.mdb_cursor_open(_transaction._handle, dbHandle, out handle));
29+
30+
return handle;
31+
}
32+
33+
private void CloseCursor(IntPtr cursorHandle)
34+
{
35+
NativeMethods.Library.mdb_cursor_close(cursorHandle);
36+
}
37+
38+
public LightningCursor OpenCursor(LightningDatabase db)
39+
{
40+
var handle = CreateCursorHandle(db._handle);
41+
_cursors.Add(handle);
42+
43+
return new LightningCursor(db, _transaction, handle);
44+
}
45+
46+
public void CloseCursor(LightningCursor cursor)
47+
{
48+
try
49+
{
50+
CloseCursor(cursor._handle);
51+
}
52+
finally
53+
{
54+
_cursors.Remove(cursor._handle);
55+
}
56+
}
57+
58+
public void CloseAll()
59+
{
60+
foreach (var handle in _cursors)
61+
CloseCursor(handle);
62+
63+
_cursors.Clear();
64+
}
1065
}
1166
}

src/LightningDB/IClosingEventSource.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/LightningDB/LightningCursor.cs

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,54 +9,28 @@ namespace LightningDB
99
/// </summary>
1010
public class LightningCursor : IDisposable
1111
{
12-
private readonly IntPtr _handle;
12+
internal readonly IntPtr _handle;
1313
private bool _shouldDispose;
1414

1515
/// <summary>
1616
/// Creates new instance of LightningCursor
1717
/// </summary>
1818
/// <param name="db">Database</param>
1919
/// <param name="txn">Transaction</param>
20-
internal LightningCursor(LightningDatabase db, LightningTransaction txn)
20+
internal LightningCursor(LightningDatabase db, LightningTransaction txn, IntPtr handle)
2121
{
2222
if (db == null)
2323
throw new ArgumentNullException("db");
2424

2525
if (txn == null)
2626
throw new ArgumentNullException("txn");
2727

28-
IntPtr handle = default(IntPtr);
29-
NativeMethods.Execute(lib => lib.mdb_cursor_open(txn._handle, db._handle, out handle));
30-
3128
_handle = handle;
3229

3330
this.Database = db;
3431
this.Transaction = txn;
3532

3633
_shouldDispose = true;
37-
38-
throw new NotImplementedException("Implement cursor manager");
39-
/*if (txn.IsReadOnly)
40-
this.Environment.Closing += EnvironmentOrTransactionClosing;
41-
else
42-
this.Transaction.Closing += EnvironmentOrTransactionClosing;*/
43-
}
44-
45-
private void EnvironmentOrTransactionClosing(object sender, EventArgs e)
46-
{
47-
try
48-
{
49-
this.Close();
50-
}
51-
catch { }
52-
}
53-
54-
private void DetachClosingHandler()
55-
{
56-
/*if (this.Transaction.IsReadOnly)
57-
this.Environment.Closing -= EnvironmentOrTransactionClosing;
58-
else
59-
this.Transaction.Closing -= EnvironmentOrTransactionClosing;*/
6034
}
6135

6236
/// <summary>
@@ -349,14 +323,7 @@ public void Renew(LightningTransaction txn)
349323
/// </summary>
350324
public void Close()
351325
{
352-
try
353-
{
354-
NativeMethods.Library.mdb_cursor_close(_handle);
355-
}
356-
finally
357-
{
358-
this.DetachClosingHandler();
359-
}
326+
Transaction.CursorManager.CloseCursor(this);
360327
}
361328

362329
/// <summary>

src/LightningDB/LightningDB.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@
9999
<Compile Include="CursorDeleteOption.cs" />
100100
<Compile Include="CursorOperation.cs" />
101101
<Compile Include="DatabaseOpenFlags.cs" />
102-
<Compile Include="IClosingEventSource.cs" />
103102
<Compile Include="LightningClosingEventArgs.cs" />
104103
<Compile Include="LightningCursor.cs" />
105104
<Compile Include="LightningDatabase.cs" />

src/LightningDB/LightningEnvironment.cs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace LightningDB
1111
/// <summary>
1212
/// LMDB Environment.
1313
/// </summary>
14-
public class LightningEnvironment : IClosingEventSource, IDisposable
14+
public class LightningEnvironment : IDisposable
1515
{
1616
private readonly UnixAccessMode _accessMode;
1717
private readonly EnvironmentOpenFlags _openFlags;
@@ -66,11 +66,6 @@ public LightningEnvironment(string directory, EnvironmentOpenFlags openFlags = E
6666
defaultConverters.RegisterDefault(this);
6767
}
6868

69-
/// <summary>
70-
/// Triggered when the environment is going to close.
71-
/// </summary>
72-
public event EventHandler<LightningClosingEventArgs> Closing;
73-
7469
/// <summary>
7570
/// Whether the environment is opened.
7671
/// </summary>
@@ -189,8 +184,6 @@ public void Close()
189184
if (!this.IsOpened)
190185
return;
191186

192-
this.OnClosing();
193-
194187
_transactionManager.AbortAll();
195188
_databaseManager.CloseAll();
196189

@@ -201,15 +194,6 @@ public void Close()
201194
_shouldDispose = false;
202195
}
203196

204-
/// <summary>
205-
/// Called when the environment is going to close.
206-
/// </summary>
207-
protected virtual void OnClosing()
208-
{
209-
if (this.Closing != null)
210-
this.Closing(this, new LightningClosingEventArgs(true));
211-
}
212-
213197
/// <summary>
214198
/// Create a transaction for use with the environment.
215199
/// The transaction handle may be discarded using Abort() or Commit().

src/LightningDB/LightningTransaction.cs

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public class LightningTransaction : IDisposable
1818
internal IntPtr _handle;
1919

2020
private readonly TransactionManager _subTransactionsManager;
21+
private readonly CursorManager _cursorManager;
2122

2223
/// <summary>
2324
/// Created new instance of LightningTransaction
@@ -37,10 +38,13 @@ internal LightningTransaction(LightningEnvironment environment, IntPtr handle, L
3738

3839
_handle = handle;
3940
_subTransactionsManager = new TransactionManager(environment, this);
41+
_cursorManager = new CursorManager(this);
4042
}
4143

4244
internal TransactionManager SubTransactionsManager { get { return _subTransactionsManager; } }
4345

46+
internal CursorManager CursorManager { get { return _cursorManager; } }
47+
4448
/// <summary>
4549
/// Current transaction state.
4650
/// </summary>
@@ -96,7 +100,7 @@ public void DropDatabase(LightningDatabase db, bool delete)
96100
/// <param name="db">A database.</param>
97101
public LightningCursor CreateCursor(LightningDatabase db)
98102
{
99-
return new LightningCursor(db, this);
103+
return CursorManager.OpenCursor(db);
100104
}
101105

102106
private bool TryGetInternal(UInt32 dbi, byte[] key, out Func<byte[]> valueFactory)
@@ -259,18 +263,40 @@ private void NotifyDiscarded()
259263
manager.WasDiscarded(this);
260264
}
261265

266+
private void Discard(Action body)
267+
{
268+
try
269+
{
270+
_subTransactionsManager.AbortAll();
271+
}
272+
finally
273+
{
274+
try
275+
{
276+
CursorManager.CloseAll();
277+
}
278+
finally
279+
{
280+
try
281+
{
282+
body.Invoke();
283+
}
284+
finally
285+
{
286+
NotifyDiscarded();
287+
}
288+
}
289+
}
290+
}
291+
262292
/// <summary>
263293
/// Commit all the operations of a transaction into the database.
264294
/// All cursors opened within the transaction will be closed by this call.
265295
/// The cursors and transaction handle will be freed and must not be used again after this call.
266296
/// </summary>
267297
public void Commit()
268298
{
269-
try
270-
{
271-
_subTransactionsManager.AbortAll();
272-
}
273-
finally
299+
Discard(() =>
274300
{
275301
try
276302
{
@@ -285,7 +311,7 @@ public void Commit()
285311
this.Abort();
286312
throw;
287313
}
288-
}
314+
});
289315
}
290316

291317
/// <summary>
@@ -295,22 +321,11 @@ public void Commit()
295321
/// </summary>
296322
public void Abort()
297323
{
298-
try
299-
{
300-
_subTransactionsManager.AbortAll();
301-
}
302-
finally
324+
Discard(() =>
303325
{
304-
try
305-
{
306-
this.State = LightningTransactionState.Aborted;
307-
NativeMethods.Library.mdb_txn_abort(_handle);
308-
}
309-
finally
310-
{
311-
NotifyDiscarded();
312-
}
313-
}
326+
this.State = LightningTransactionState.Aborted;
327+
NativeMethods.Library.mdb_txn_abort(_handle);
328+
});
314329
}
315330

316331
/// <summary>

0 commit comments

Comments
 (0)