From fa7228962bb4bc27b721564dc78437f6180b3841 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 12 Jul 2013 13:36:05 -0700 Subject: [PATCH 1/5] Bump version to 0.9.7 --- libraries/liblmdb/lmdb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/liblmdb/lmdb.h b/libraries/liblmdb/lmdb.h index 9f00a04202..7c5a63f0e9 100644 --- a/libraries/liblmdb/lmdb.h +++ b/libraries/liblmdb/lmdb.h @@ -166,7 +166,7 @@ typedef int mdb_filehandle_t; /** Library minor version */ #define MDB_VERSION_MINOR 9 /** Library patch version */ -#define MDB_VERSION_PATCH 6 +#define MDB_VERSION_PATCH 7 /** Combine args a,b,c into a single integer for easy version comparisons */ #define MDB_VERINT(a,b,c) (((a) << 24) | ((b) << 16) | (c)) From 8ae56c34d537f93d6dc2e7f84fa45d09b42f05ac Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 12 Jul 2013 13:55:18 -0700 Subject: [PATCH 2/5] Tweak comments, defaults should be OK already --- libraries/liblmdb/Makefile | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libraries/liblmdb/Makefile b/libraries/liblmdb/Makefile index 25c52ada8e..8255d8b438 100644 --- a/libraries/liblmdb/Makefile +++ b/libraries/liblmdb/Makefile @@ -3,7 +3,9 @@ ######################################################################## # Configuration. The compiler options must enable threaded compilation. # -# Preprocessor macros (for CPPFLAGS) of interest: +# Preprocessor macros (for CPPFLAGS) of interest... +# Note that the defaults should already be correct for most +# platforms; you should not need to change any of these: # # To compile successfully if the default does not: # - MDB_USE_POSIX_SEM (enabled by default on BSD, Apple) @@ -11,7 +13,7 @@ # semaphores and shared mutexes have different behaviors and # different problems, see the Caveats section in lmdb.h. # -# For best performence or to compile successfully: +# For best performance or to compile successfully: # - MDB_DSYNC = "O_DSYNC" (default) or "O_SYNC" (less efficient) # If O_DSYNC is undefined but exists in /usr/include, # preferably set some compiler flag to get the definition. @@ -25,14 +27,13 @@ # Data format: # - MDB_MAXKEYSIZE # Controls data packing and limits, see mdb.c. -# -# Debugging: -# - MDB_DEBUG, MDB_PARANOID. +# You might need to change this if the default size is too small. # CC = gcc W = -W -Wall -Wno-unused-parameter -Wbad-function-cast +THREADS = -pthread OPT = -O2 -g -CFLAGS = -pthread $(OPT) $(W) $(XCFLAGS) +CFLAGS = $(THREADS) $(OPT) $(W) $(XCFLAGS) LDLIBS = SOLIBS = prefix = /usr/local From 56a41d87d42568328413f6e2a6197c2ae0dc67bd Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 14 Jul 2013 08:20:18 -0700 Subject: [PATCH 3/5] Fix stale sub-cursor C_INIT flag Whenever we enter cursor_set() the sub-cursor's flag must be cleared. If the new cursor position has valid subdata it will be initialized again, if not then the sub-cursor has nothing to point to. --- libraries/liblmdb/mdb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index df88adcd27..3f8dc732bb 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -4856,6 +4856,9 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data, assert(key); assert(key->mv_size > 0); + if (mc->mc_db->md_flags & MDB_DUPSORT) + mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); + /* See if we're already on the right page */ if (mc->mc_flags & C_INITIALIZED) { MDB_val nodekey; From 2c3488aeebf10edaf740ae9b4daba0e7ed89c8d6 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 14 Jul 2013 08:28:26 -0700 Subject: [PATCH 4/5] More for stale sub-cursor flags Same fix for cursor_first/last. --- libraries/liblmdb/mdb.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 3f8dc732bb..102bd77591 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -4856,7 +4856,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data, assert(key); assert(key->mv_size > 0); - if (mc->mc_db->md_flags & MDB_DUPSORT) + if (mc->mc_xcursor) mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); /* See if we're already on the right page */ @@ -5031,6 +5031,9 @@ mdb_cursor_first(MDB_cursor *mc, MDB_val *key, MDB_val *data) int rc; MDB_node *leaf; + if (mc->mc_xcursor) + mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); + if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) { rc = mdb_page_search(mc, NULL, 0); if (rc != MDB_SUCCESS) @@ -5057,8 +5060,6 @@ mdb_cursor_first(MDB_cursor *mc, MDB_val *key, MDB_val *data) if (rc) return rc; } else { - if (mc->mc_xcursor) - mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS) return rc; } @@ -5074,6 +5075,9 @@ mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data) int rc; MDB_node *leaf; + if (mc->mc_xcursor) + mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); + if (!(mc->mc_flags & C_EOF)) { if (!(mc->mc_flags & C_INITIALIZED) || mc->mc_top) { @@ -5105,8 +5109,6 @@ mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data) if (rc) return rc; } else { - if (mc->mc_xcursor) - mc->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); if ((rc = mdb_node_read(mc->mc_txn, leaf, data)) != MDB_SUCCESS) return rc; } From 501eac2fc48899aa7f3971666eaef1eb9e2f387c Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 14 Jul 2013 16:53:04 -0700 Subject: [PATCH 5/5] Fix child txn dirty_room counts in spill/unspill Don't count pages twice if they're already accounted in an ancestor txn. --- libraries/liblmdb/mdb.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 102bd77591..2f997737f9 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -1478,7 +1478,26 @@ mdb_page_spill(MDB_cursor *m0, MDB_val *key, MDB_val *data) mdb_cursorpages_mark(m0, P_DIRTY|P_KEEP); if (rc == 0) { - txn->mt_dirty_room = MDB_IDL_UM_MAX - dl[0].mid; + if (txn->mt_parent) { + MDB_txn *tx2; + pgno_t pgno = dl[i].mid; + txn->mt_dirty_room = txn->mt_parent->mt_dirty_room - dl[0].mid; + /* dirty pages that are dirty in an ancestor don't + * count against this txn's dirty_room. + */ + for (i=1; i<=dl[0].mid; i++) { + for (tx2 = txn->mt_parent; tx2; tx2 = tx2->mt_parent) { + j = mdb_mid2l_search(tx2->mt_u.dirty_list, pgno); + if (j <= tx2->mt_u.dirty_list[0].mid && + tx2->mt_u.dirty_list[j].mid == pgno) { + txn->mt_dirty_room++; + break; + } + } + } + } else { + txn->mt_dirty_room = MDB_IDL_UM_MAX - dl[0].mid; + } txn->mt_flags |= MDB_TXN_SPILLS; } return rc; @@ -1743,6 +1762,22 @@ mdb_page_unspill(MDB_txn *tx0, MDB_page *mp, MDB_page **ret) } /* otherwise, if belonging to a parent txn, the * page remains spilled until child commits */ + + if (txn->mt_parent) { + MDB_txn *tx2; + /* If this page is also in a parent's dirty list, then + * it's already accounted in dirty_room, and we need to + * cancel out the decrement that mdb_page_dirty does. + */ + for (tx2 = txn->mt_parent; tx2; tx2 = tx2->mt_parent) { + x = mdb_mid2l_search(tx2->mt_u.dirty_list, pgno); + if (x <= tx2->mt_u.dirty_list[0].mid && + tx2->mt_u.dirty_list[x].mid == pgno) { + txn->mt_dirty_room++; + break; + } + } + } mdb_page_dirty(tx0, np); np->mp_flags |= P_DIRTY; *ret = np;