* BerkeleyDB API, but much simplified.
*/
/*
- * Copyright 2011-2016 Howard Chu, Symas Corp.
+ * Copyright 2011-2017 Howard Chu, Symas Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/** The version number for a database's datafile format. */
#define MDB_DATA_VERSION ((MDB_DEVEL) ? 999 : 1)
/** The version number for a database's lockfile format. */
-#define MDB_LOCK_VERSION ((MDB_DEVEL) ? 999 : 1)
+#define MDB_LOCK_VERSION ((MDB_DEVEL) ? 999 : 2)
/** @brief The max size of a key we can write, or 0 for computed max.
*
uint32_t mtb_magic;
/** Format of this lock file. Must be set to #MDB_LOCK_FORMAT. */
uint32_t mtb_format;
+ /** The ID of the last transaction committed to the database.
+ * This is recorded here only for convenience; the value can always
+ * be determined by reading the main database meta pages.
+ */
+ volatile txnid_t mtb_txnid;
+ /** The number of slots that have been used in the reader table.
+ * This always records the maximum count, it is not decremented
+ * when readers release their slots.
+ */
+ volatile unsigned mtb_numreaders;
#if defined(_WIN32) || defined(MDB_USE_POSIX_SEM)
char mtb_rmname[MNAME_LEN];
#elif defined(MDB_USE_SYSV_SEM)
*/
mdb_mutex_t mtb_rmutex;
#endif
- /** The ID of the last transaction committed to the database.
- * This is recorded here only for convenience; the value can always
- * be determined by reading the main database meta pages.
- */
- volatile txnid_t mtb_txnid;
- /** The number of slots that have been used in the reader table.
- * This always records the maximum count, it is not decremented
- * when readers release their slots.
- */
- volatile unsigned mtb_numreaders;
} MDB_txbody;
/** The actual reader table definition. */
mdb_cursor_unref(MDB_cursor *mc)
{
int i;
- if (!mc->mc_snum || !mc->mc_pg[0] || IS_SUBP(mc->mc_pg[0]))
- return;
- for (i=0; i<mc->mc_snum; i++)
- mdb_page_unref(mc->mc_txn, mc->mc_pg[i]);
- if (mc->mc_ovpg) {
- mdb_page_unref(mc->mc_txn, mc->mc_ovpg);
- mc->mc_ovpg = 0;
+ if (mc->mc_txn->mt_rpages[0].mid) {
+ if (!mc->mc_snum || !mc->mc_pg[0] || IS_SUBP(mc->mc_pg[0]))
+ return;
+ for (i=0; i<mc->mc_snum; i++)
+ mdb_page_unref(mc->mc_txn, mc->mc_pg[i]);
+ if (mc->mc_ovpg) {
+ mdb_page_unref(mc->mc_txn, mc->mc_ovpg);
+ mc->mc_ovpg = 0;
+ }
}
mc->mc_snum = mc->mc_top = 0;
mc->mc_pg[0] = NULL;
mp = mc->mc_pg[mc->mc_top];
- if ((mc->mc_flags & C_EOF) && mc->mc_ki[mc->mc_top] >= NUMKEYS(mp)-1)
- return MDB_NOTFOUND;
+ if (mc->mc_flags & C_EOF) {
+ if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mp)-1)
+ return MDB_NOTFOUND;
+ mc->mc_flags ^= C_EOF;
+ }
if (mc->mc_db->md_flags & MDB_DUPSORT) {
leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
if (!(mc->mc_flags & C_INITIALIZED))
return EINVAL;
- if (!mc->mc_snum || (mc->mc_flags & C_EOF))
+ if (!mc->mc_snum)
return MDB_NOTFOUND;
+ if (mc->mc_flags & C_EOF) {
+ if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top]))
+ return MDB_NOTFOUND;
+ mc->mc_flags ^= C_EOF;
+ }
+
leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
*countp = 1;