1
0
Fork 0
forked from blue/lmdbal

Cursors get closed after transaction that open them

This commit is contained in:
Blue 2024-12-24 14:59:58 +02:00
parent 68ea7df6a9
commit e88efb458f
Signed by untrusted user: blue
GPG key ID: 9B203B252A63EE38
12 changed files with 225 additions and 56 deletions

View file

@ -19,6 +19,7 @@
#pragma once
#include "cursor.h"
#include <iostream>
/**
@ -84,6 +85,10 @@ LMDBAL::Cursor<K, V>::Cursor(Cursor&& other):
if (id != 0)
storage->cursors[id] = this;
if (state == openedPublic)
storage->attachCursorToTransaction(id, cursor, this);
other.freed();
}
@ -110,6 +115,9 @@ LMDBAL::Cursor<K, V>& LMDBAL::Cursor<K, V>::operator = (Cursor&& other) {
other.state = closed;
storage->cursors[id] = this;
if (state == openedPublic)
storage->attachCursorToTransaction(id, cursor, this);
}
return *this;
@ -184,7 +192,20 @@ bool LMDBAL::Cursor<K, V>::empty () const {
*/
template<class K, class V>
void LMDBAL::Cursor<K, V>::terminated () {
close(); //for now it's the same, but if I ever going to make writable cursor - here is where it's gonna be different
switch (state) {
case openedPublic:
storage->_mdbCursorClose(cursor);
state = closed;
break;
case openedPrivate:
storage->closeCursorTransaction(cursor);
state = closed;
break;
default:
break;
}
}
/**
@ -205,17 +226,11 @@ void LMDBAL::Cursor<K, V>::open () {
if (empty())
throw CursorEmpty(openCursorMethodName);
storage->ensureOpened(openCursorMethodName);
switch (state) {
case closed: {
TransactionID txn = storage->beginReadOnlyTransaction();
int result = storage->_mdbCursorOpen(txn, &cursor);
if (result != MDB_SUCCESS)
storage->throwUnknown(result, txn);
storage->transactionStarted(txn, true);
case closed:
storage->openCursorTransaction(&cursor);
state = openedPrivate;
} break;
break;
default:
break;
}
@ -250,6 +265,7 @@ void LMDBAL::Cursor<K, V>::open (const Transaction& transaction) {
if (result != MDB_SUCCESS)
storage->throwUnknown(result);
storage->attachCursorToTransaction(id, cursor, this);
state = openedPublic;
} break;
default:
@ -285,15 +301,24 @@ void LMDBAL::Cursor<K, V>::renew () {
TransactionID txn = storage->_mdbCursorTxn(cursor);
storage->abortTransaction(txn);
storage->transactionAborted(txn);
[[fallthrough]];
txn = storage->beginReadOnlyTransaction();
int result = storage->_mdbCursorRenew(txn, cursor);
if (result != MDB_SUCCESS)
storage->throwUnknown(result, txn);
storage->transactionStarted(txn, true);
state = openedPrivate;
}
case openedPublic: {
storage->disconnectCursorFromTransaction(id, cursor);
TransactionID txn = storage->beginReadOnlyTransaction();
int result = storage->_mdbCursorRenew(txn, cursor);
if (result != MDB_SUCCESS)
storage->throwUnknown(result, txn);
storage->transactionStarted(txn, true);
storage->attachCursorToTransaction(id, cursor, this);
state = openedPrivate;
} break;
default:
@ -330,17 +355,24 @@ void LMDBAL::Cursor<K, V>::renew (const Transaction& transaction) {
TransactionID txn = storage->extractTransactionId(transaction, renewCursorMethodName);
switch (state) {
case openedPrivate: {
TransactionID txn = storage->_mdbCursorTxn(cursor);
storage->abortTransaction(txn);
storage->transactionAborted(txn);
[[fallthrough]];
}
case openedPublic: {
TransactionID txnOld = storage->_mdbCursorTxn(cursor);
storage->abortTransaction(txnOld);
storage->transactionAborted(txnOld);
int result = storage->_mdbCursorRenew(txn, cursor);
if (result != MDB_SUCCESS)
storage->throwUnknown(result);
state = openedPublic;
}
case openedPublic: {
storage->disconnectCursorFromTransaction(id, cursor);
int result = storage->_mdbCursorRenew(txn, cursor);
if (result != MDB_SUCCESS)
storage->throwUnknown(result);
storage->attachCursorToTransaction(id, cursor, this);
state = openedPublic;
} break;
default:
break;
@ -360,19 +392,17 @@ void LMDBAL::Cursor<K, V>::renew (const Transaction& transaction) {
template<class K, class V>
void LMDBAL::Cursor<K, V>::close () {
switch (state) {
case openedPublic: {
case openedPublic:
storage->disconnectCursorFromTransaction(id, cursor);
storage->_mdbCursorClose(cursor);
state = closed;
} break;
case openedPrivate: {
TransactionID txn = storage->_mdbCursorTxn(cursor);
storage->_mdbCursorClose(cursor);
storage->abortTransaction(txn);
storage->transactionAborted(txn);
break;
case openedPrivate:
storage->closeCursorTransaction(cursor);
state = closed;
} break;
break;
default:
break;
}