Hallvard Breien Furuseth:
Sofar the abstraction layer already hides the LMDB-specific MAP_FULL and MAP_RESIZED error conditions. If this abstraction layer needs additional code in order to maintain MDB cursor sanity, then please educate me.
ldmb.h says --
mdb_env_set_mapsize(): "It may be called at later times if no transactions are active in this process. Note that the library does not check for this condition, the caller must ensure it explicitly." MDB_NOLOCK: "[caller] must ensure that no readers are using old transactions while a writer is active. The simplest approach is to use an exclusive lock so that no readers may be active at all when a writer begins."
That's why I talked about saving the cursor position and restoring it - cursors are per-transaction and you need a new transaction.
I can remember the last key from mdb_cursor_get() and set the cursor to that key. There does not appear to be a cursor "save" operation in the API documentation http://symas.com/mdb/doc/group__mdb.html.
Maybe you should have a single write-transaction with several cursors, instead of several transactions. That also cures the "long-lived reader" problem.
That would result in delayed delete operations, and break correctness. If a database entry is updated after it is scheduled for delete, then the entry must not be deleted.
Also, I am concerned that would pollute my database-neutral API with LMDB-specific details.
Wietse
Howard, maybe NOLOCK should keep the reader table and just drop the locks? More work though.
-- Hallvard