Commit Graph

17 Commits

Author SHA1 Message Date
Martchus bb985870f0 Avoid overflow when running out of IDs
* Throw an exception instead
* Add function that allows re-using lower IDs instead
* Move functions to query IDs to read-only operations
2022-04-15 19:18:35 +02:00
Martchus 6c21fe7cb1 Use type alias for ID type 2022-02-21 22:57:15 +01:00
Martchus 2e7d278c9b Apply uniform formatting via clang-format 2022-01-30 21:14:43 +01:00
Martchus b833bfef3b Move everything under a namespace 2022-01-18 22:09:12 +01:00
Jonas Schäfer 3c57c6a113 Hide MDB*Transaction behind a unique_ptr front
This is to prevent the issue with Object Slicing. With the previous
solution (where MDB*Transaction are normal objects), consider the
following code:

    MDBRWTransaction txn = env.getRWTransaction();

    //! Invalid: We explicitly break this move because it would be
    //! unsafe:
    // MDBROTransaction ro_txn(std::move(txn));

    //! Valid, RW inherits from RO now, so we can bind an RO
    //! reference to an RW transaction.
    MDBROTransaction &ro_txn = txn;

    //! Dangerous!!
    MDBROTransaction ro_txn2(std::move(ro_txn));

The last move there breaks the semantics of the RW transaction which
is bound to the reference ro_txn. It looses its RW cursors, which
remain partly inside the txn instance. All kinds of weird and bad
things can happen here. For instance, the ro_txn2 would go out of
scope before the txn, calling the destructor MDBROTransaction
destructor (which defaults to commit instead of abort!) and only
freeing parts of the cursors. Only then the MDBRWTransaction
destructor is called, which will free the cursors which belong to
the RW transaction which has already been committed.

The only safe way to prevent Object Slicing in this scenario I
could come up with is to disallow moves of the objects altogether
and instead use unique_ptr as front for them. This also removes
an additional dynamic allocation per RW transaction (for the
cursor vector), since the address of that vector is now constant
over the lifetime of the transaction without indirection.
2019-11-11 21:23:20 +01:00
Jonas Schäfer d2b0ee057a Re-work the class hierarchy of cursors and transactions
MDBRWTransaction now inherits from MDBROTransaction. Both
transaction types will free their cursors before aborting or
committing. In addition, transactions are now virtual classes.

The reason for this is that RW and RO transactions are handled
very differently in LMDB. Nevertheless, it is very useful to be
able to write read-only code in a way which also can use an RW
transaction. This saves code duplication or unnecessary templates.

Since the only methods which are reqiured to be virtual on
transactions for this to work are the destructor and the
abort/commit methods, the overhead should be neglegible.

This also comes in very handy when going forward to implement
nested transactions, because it is not possible to nest RO
transactions below RW transactions, exacerbating the issue
described above.

Fixes #7 en passant.
2019-11-11 21:23:20 +01:00
bert hubert 59b3b602fa lots of changes 2018-12-27 17:49:41 +01:00
bert hubert 4c1b5e404c get now returns an id, making id=0 special, split out our sample code 2018-12-17 14:56:01 +01:00
bert hubert 3277381170 s/insert/put/ 2018-12-16 21:46:53 +01:00
bert hubert 654e782b5f add a lot of comments for future ahu 2018-12-16 20:28:49 +01:00
bert hubert bb981d6d31 add compound keys and iterator-- 2018-12-16 15:58:38 +01:00
bert hubert a144209f12 find, begin 2018-12-15 21:06:47 +01:00
bert hubert 5af0bb3e67 readonly transactions, common implementation 2018-12-15 17:53:29 +01:00
bert hubert f11d89dd4a more docs + cleanups 2018-12-15 01:54:29 +01:00
bert hubert d3f94d67c3 tuplify, macrofy, add cardinality, templated find, get etc 2018-12-15 00:46:15 +01:00
bert hubert ada45b45ba interim pre-tuple 2018-12-14 23:46:46 +01:00
bert hubert d98d657765 eradicate some MDB_dbi use, more string_view 2018-12-14 23:00:44 +01:00