From 8297bfe02886f07e7da10fbfb866828eaad13f59 Mon Sep 17 00:00:00 2001 From: Orivej Desh Date: Sun, 22 Nov 2015 00:59:55 +0000 Subject: [PATCH 01/16] ITS#8319 mdb_load: explain readline and mdb_cursor_put errors --- libraries/liblmdb/mdb_load.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/liblmdb/mdb_load.c b/libraries/liblmdb/mdb_load.c index 160bc1b885..5373a9d5d6 100644 --- a/libraries/liblmdb/mdb_load.c +++ b/libraries/liblmdb/mdb_load.c @@ -400,20 +400,22 @@ int main(int argc, char *argv[]) while(1) { rc = readline(&key, &kbuf); - if (rc == EOF) + if (rc) /* rc == EOF */ break; - if (rc) - goto txn_abort; rc = readline(&data, &dbuf); - if (rc) + if (rc) { + fprintf(stderr, "%s: line %" Z "d: failed to read key value\n", prog, lineno); goto txn_abort; - + } + rc = mdb_cursor_put(mc, &key, &data, putflags); if (rc == MDB_KEYEXIST && putflags) continue; - if (rc) + if (rc) { + fprintf(stderr, "mdb_cursor_put failed, error %d %s\n", rc, mdb_strerror(rc)); goto txn_abort; + } batch++; if (batch == 100) { rc = mdb_txn_commit(txn); From 00f635d30431050c94c44145db214b8eeb9455ce Mon Sep 17 00:00:00 2001 From: Orivej Desh Date: Sun, 22 Nov 2015 01:15:14 +0000 Subject: [PATCH 02/16] ITS#8320 mdb_load: fix loading data from simple text files mdb_load -T was supposed to read escaped text, but 21b51cb7 "Add mdb_load" made it read hex. --- libraries/liblmdb/mdb_load.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/liblmdb/mdb_load.c b/libraries/liblmdb/mdb_load.c index 5373a9d5d6..d2f0968188 100644 --- a/libraries/liblmdb/mdb_load.c +++ b/libraries/liblmdb/mdb_load.c @@ -327,7 +327,7 @@ int main(int argc, char *argv[]) putflags = MDB_NOOVERWRITE|MDB_NODUPDATA; break; case 'T': - mode |= NOHDR; + mode |= NOHDR | PRINT; break; default: usage(); From 9e3101d31d1bcd580b408b5c13fe62c7714596dd Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 23 Nov 2015 02:02:36 +0000 Subject: [PATCH 03/16] ITS#8319, 8320 --- libraries/liblmdb/CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/liblmdb/CHANGES b/libraries/liblmdb/CHANGES index b0aad290ae..6322138a1f 100644 --- a/libraries/liblmdb/CHANGES +++ b/libraries/liblmdb/CHANGES @@ -22,6 +22,8 @@ LMDB 0.9.17 Release Engineering Fix ITS#8315 dirty_room in nested txn Fix ITS#8316 page_merge cursor tracking Fix ITS#8321 cursor tracking + Fix ITS#8319 mdb_load error messages + Fix ITS#8320 mdb_load plaintext input Added mdb_txn_id() (ITS#7994) Added robust mutex support Miscellaneous cleanup/simplification From c11ef29ffab1f2630c2b294117bfad019d5e3509 Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Mon, 23 Nov 2015 13:03:09 +0100 Subject: [PATCH 04/16] CURSOR_TMP_[UN]TRACK() -> WITH_CURSOR_TRACKING() --- libraries/liblmdb/mdb.c | 46 +++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index c5174e983a..7fd1d384b5 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -7524,21 +7524,21 @@ mdb_update_key(MDB_cursor *mc, MDB_val *key) static void mdb_cursor_copy(const MDB_cursor *csrc, MDB_cursor *cdst); -/** Track a temporary cursor */ -#define CURSOR_TMP_TRACK(mc, mn, dummy, tracked) \ - if (mc->mc_flags & C_SUB) { \ +/** Perform \b act while tracking temporary cursor \b mn */ +#define WITH_CURSOR_TRACKING(mn, act) do { \ + MDB_cursor dummy, *tracked, **tp = &(mn).mc_txn->mt_cursors[mn.mc_dbi]; \ + if ((mn).mc_flags & C_SUB) { \ dummy.mc_flags = C_INITIALIZED; \ - dummy.mc_xcursor = (MDB_xcursor *)&mn; \ + dummy.mc_xcursor = (MDB_xcursor *)&(mn); \ tracked = &dummy; \ } else { \ - tracked = &mn; \ + tracked = &(mn); \ } \ - tracked->mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi]; \ - mc->mc_txn->mt_cursors[mc->mc_dbi] = tracked - -/** Stop tracking a temporary cursor */ -#define CURSOR_TMP_UNTRACK(mc, tracked) \ - mc->mc_txn->mt_cursors[mc->mc_dbi] = tracked->mc_next + tracked->mc_next = *tp; \ + *tp = tracked; \ + { act; } \ + *tp = tracked->mc_next; \ +} while (0) /** Move a node from csrc to cdst. */ @@ -7695,7 +7695,6 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) */ if (csrc->mc_ki[csrc->mc_top] == 0) { if (csrc->mc_ki[csrc->mc_top-1] != 0) { - MDB_cursor dummy, *tracked; if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) { key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], 0, key.mv_size); } else { @@ -7709,9 +7708,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) mn.mc_snum--; mn.mc_top--; /* We want mdb_rebalance to find mn when doing fixups */ - CURSOR_TMP_TRACK(csrc, mn, dummy, tracked); - rc = mdb_update_key(&mn, &key); - CURSOR_TMP_UNTRACK(csrc, tracked); + WITH_CURSOR_TRACKING(mn, + rc = mdb_update_key(&mn, &key)); if (rc) return rc; } @@ -7728,7 +7726,6 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) if (cdst->mc_ki[cdst->mc_top] == 0) { if (cdst->mc_ki[cdst->mc_top-1] != 0) { - MDB_cursor dummy, *tracked; if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) { key.mv_data = LEAF2KEY(cdst->mc_pg[cdst->mc_top], 0, key.mv_size); } else { @@ -7742,9 +7739,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) mn.mc_snum--; mn.mc_top--; /* We want mdb_rebalance to find mn when doing fixups */ - CURSOR_TMP_TRACK(cdst, mn, dummy, tracked); - rc = mdb_update_key(&mn, &key); - CURSOR_TMP_UNTRACK(cdst, tracked); + WITH_CURSOR_TRACKING(mn, + rc = mdb_update_key(&mn, &key)); if (rc) return rc; } @@ -8103,13 +8099,11 @@ mdb_rebalance(MDB_cursor *mc) if (!fromleft) { rc = mdb_page_merge(&mn, mc); } else { - MDB_cursor dummy, *tracked; oldki += NUMKEYS(mn.mc_pg[mn.mc_top]); mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1; /* We want mdb_rebalance to find mn when doing fixups */ - CURSOR_TMP_TRACK(mc, mn, dummy, tracked); - rc = mdb_page_merge(mc, &mn); - CURSOR_TMP_UNTRACK(mc, tracked); + WITH_CURSOR_TRACKING(mn, + rc = mdb_page_merge(mc, &mn)); mdb_cursor_copy(&mn, mc); } mc->mc_flags &= ~C_EOF; @@ -8473,14 +8467,12 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno */ if (SIZELEFT(mn.mc_pg[ptop]) < mdb_branch_size(env, &sepkey)) { int snum = mc->mc_snum; - MDB_cursor dummy, *tracked; mn.mc_snum--; mn.mc_top--; did_split = 1; /* We want other splits to find mn when doing fixups */ - CURSOR_TMP_TRACK(mc, mn, dummy, tracked); - rc = mdb_page_split(&mn, &sepkey, NULL, rp->mp_pgno, 0); - CURSOR_TMP_UNTRACK(mc, tracked); + WITH_CURSOR_TRACKING(mn, + rc = mdb_page_split(&mn, &sepkey, NULL, rp->mp_pgno, 0)); if (rc) goto done; From 75bca7f31136349858eed77bd93715694a96d256 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 23 Nov 2015 13:11:29 +0000 Subject: [PATCH 05/16] ITS#8323 Fix nested commit Must remove our spilled pages from parent's dirty list --- libraries/liblmdb/mdb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 7fd1d384b5..e9deb7c27c 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -3431,6 +3431,25 @@ mdb_txn_commit(MDB_txn *txn) pspill[0] = y; } + /* Remove anything in our spill list from parent's dirty list */ + if (txn->mt_spill_pgs && txn->mt_spill_pgs[0]) { + for (i=1; i<=txn->mt_spill_pgs[0]; i++) { + MDB_ID pn = txn->mt_spill_pgs[i]; + if (pn & 1) + continue; /* deleted spillpg */ + pn >>= 1; + y = mdb_mid2l_search(dst, pn); + if (y <= dst[0].mid && dst[y].mid == pn) { + free(dst[y].mptr); + while (y < dst[0].mid) { + dst[y] = dst[y+1]; + y++; + } + dst[0].mid--; + } + } + } + /* Find len = length of merging our dirty list with parent's */ x = dst[0].mid; dst[0].mid = 0; /* simplify loops */ From 00515babcc05b6a4f99b528c45187209a5092a89 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 24 Nov 2015 12:54:46 +0000 Subject: [PATCH 06/16] ITS#8321 deinit empty cursors Always unset C_INIT flag if the cursor's target DB has been deleted --- libraries/liblmdb/mdb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index e9deb7c27c..307cb4bf7f 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -5163,8 +5163,11 @@ mdb_cursor_pop(MDB_cursor *mc) mc->mc_pg[mc->mc_top]->mp_pgno, DDBI(mc), (void *) mc)); mc->mc_snum--; - if (mc->mc_snum) + if (mc->mc_snum) { mc->mc_top--; + } else { + mc->mc_flags &= ~C_INITIALIZED; + } } } @@ -6820,6 +6823,7 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags) if (flags & MDB_NODUPDATA) { /* mdb_cursor_del0() will subtract the final entry */ mc->mc_db->md_entries -= mc->mc_xcursor->mx_db.md_entries - 1; + mc->mc_xcursor->mx_cursor.mc_flags &= ~C_INITIALIZED; } else { if (!F_ISSET(leaf->mn_flags, F_SUBDATA)) { mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); @@ -6857,6 +6861,8 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags) mc->mc_db->md_entries--; mc->mc_flags |= C_DEL; return rc; + } else { + mc->mc_xcursor->mx_cursor.mc_flags &= ~C_INITIALIZED; } /* otherwise fall thru and delete the sub-DB */ } @@ -9646,6 +9652,7 @@ done: } else if (rc == MDB_NOTFOUND) { rc = MDB_SUCCESS; } + mc->mc_flags &= ~C_INITIALIZED; return rc; } From 7881fd0fa7dbfc427c2176716d1b62ece319a960 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 23 Nov 2015 18:30:24 +0000 Subject: [PATCH 07/16] ITS#8321 Fix mdb_cursor_set Always reinit mc_pg[0] if cursor is not C_INITIALIZED It might have a stale value when using nested txns --- libraries/liblmdb/mdb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 307cb4bf7f..7b5e099534 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -5878,6 +5878,8 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data, } else return MDB_NOTFOUND; } + } else { + mc->mc_pg[0] = 0; } rc = mdb_page_search(mc, key, 0); From 8e7cd2269d412c60f072b57086e6f5e7362609e5 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 24 Nov 2015 01:21:05 +0000 Subject: [PATCH 08/16] ITS#8321 mdb_put cursor needs tracking too --- libraries/liblmdb/mdb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 7b5e099534..e9c2c9f298 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -8658,7 +8658,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno m3->mc_ki[k+1] = m3->mc_ki[k]; m3->mc_pg[k+1] = m3->mc_pg[k]; } - if (m3->mc_ki[0] > nkeys) { + if (m3->mc_ki[0] >= nkeys) { m3->mc_ki[0] = 1; } else { m3->mc_ki[0] = 0; @@ -8700,6 +8700,7 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi, { MDB_cursor mc; MDB_xcursor mx; + int rc; if (!key || !data || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID)) return EINVAL; @@ -8711,7 +8712,11 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi, return (txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN; mdb_cursor_init(&mc, txn, dbi, &mx); - return mdb_cursor_put(&mc, key, data, flags); + mc.mc_next = txn->mt_cursors[dbi]; + txn->mt_cursors[dbi] = &mc; + rc = mdb_cursor_put(&mc, key, data, flags); + txn->mt_cursors[dbi] = mc.mc_next; + return rc; } #ifndef MDB_WBUF From 2b89f4baf16e40aa61fcd95311aaf341097bbd55 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 23 Nov 2015 13:19:26 +0000 Subject: [PATCH 09/16] ITS#8321 page_touch - don't fixup the cursor we just touched --- libraries/liblmdb/mdb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index e9c2c9f298..22c5d30186 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -2418,6 +2418,7 @@ done: } else { for (; m2; m2=m2->mc_next) { if (m2->mc_snum < mc->mc_snum) continue; + if (m2 == mc) continue; if (m2->mc_pg[mc->mc_top] == mp) { m2->mc_pg[mc->mc_top] = np; if ((mc->mc_db->md_flags & MDB_DUPSORT) && From 46e3f46e764ccd58cc1d323d25527a0928d8afcf Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 23 Nov 2015 16:58:57 +0000 Subject: [PATCH 10/16] ITS#8321 More cursor fixup Based on page_touch fixup from ITS#7594 but expanded: make sure sub-cursors agree with main cursors. --- libraries/liblmdb/mdb.c | 45 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 22c5d30186..3e87ea4126 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -1613,6 +1613,13 @@ mdb_cursor_chk(MDB_cursor *mc) } if (mc->mc_ki[i] >= NUMKEYS(mc->mc_pg[i])) printf("ack!\n"); + if (mc->mc_xcursor && (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { + node = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); + if (((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) && + mc->mc_xcursor->mx_cursor.mc_pg[0] != NODEDATA(node)) { + printf("blah!\n"); + } + } } #endif @@ -2423,10 +2430,10 @@ done: m2->mc_pg[mc->mc_top] = np; if ((mc->mc_db->md_flags & MDB_DUPSORT) && IS_LEAF(np) && - m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top]) + (m2->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { - MDB_node *leaf = NODEPTR(np, mc->mc_ki[mc->mc_top]); - if (!(leaf->mn_flags & F_SUBDATA)) + MDB_node *leaf = NODEPTR(np, m2->mc_ki[mc->mc_top]); + if ((leaf->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); } } @@ -7623,6 +7630,7 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) data.mv_size = NODEDSZ(srcnode); data.mv_data = NODEDATA(srcnode); } + mn.mc_xcursor = NULL; if (IS_BRANCH(cdst->mc_pg[cdst->mc_top]) && cdst->mc_ki[cdst->mc_top] == 0) { unsigned int snum = cdst->mc_snum; MDB_node *s2; @@ -7694,6 +7702,12 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top]; m3->mc_ki[csrc->mc_top-1]++; } + if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && + IS_LEAF(mps)) { + MDB_node *node = NODEPTR(m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); + if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) + m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); + } } } else /* Adding on the right, bump others down */ @@ -7714,6 +7728,12 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) } else { m3->mc_ki[csrc->mc_top]--; } + if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && + IS_LEAF(mps)) { + MDB_node *node = NODEPTR(m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); + if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) + m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); + } } } } @@ -7838,6 +7858,7 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) MDB_cursor mn; MDB_node *s2; mdb_cursor_copy(csrc, &mn); + mn.mc_xcursor = NULL; /* must find the lowest key below src */ rc = mdb_page_search_lowest(&mn); if (rc) @@ -7913,6 +7934,12 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) m3->mc_ki[top-1] > csrc->mc_ki[top-1]) { m3->mc_ki[top-1]--; } + if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && + IS_LEAF(psrc)) { + MDB_node *node = NODEPTR(m3->mc_pg[top], m3->mc_ki[top]); + if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) + m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); + } } } { @@ -8171,6 +8198,11 @@ mdb_cursor_del0(MDB_cursor *mc) else if (mc->mc_db->md_flags & MDB_DUPSORT) m3->mc_xcursor->mx_cursor.mc_flags &= ~C_INITIALIZED; } + if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { + MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); + if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) + m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); + } } } } @@ -8353,6 +8385,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno } mdb_cursor_copy(mc, &mn); + mn.mc_xcursor = NULL; mn.mc_pg[mn.mc_top] = rp; mn.mc_ki[ptop] = mc->mc_ki[ptop]+1; @@ -8683,6 +8716,12 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno m3->mc_ki[ptop] >= mc->mc_ki[ptop]) { m3->mc_ki[ptop]++; } + if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && + IS_LEAF(mp)) { + MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); + if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) + m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); + } } } DPRINTF(("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp))); From e0316e0fae73b44b4704edb9e78dd1b825c36495 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 24 Nov 2015 12:14:49 +0000 Subject: [PATCH 11/16] Cleanup C_DEL flag usage Only set it if the cursor's current position was deleted --- libraries/liblmdb/mdb.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 3e87ea4126..b8c4355836 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -6105,8 +6105,6 @@ mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_GET_KEY(leaf, key); if (data) { if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { - if (mc->mc_flags & C_DEL) - mdb_xcursor_init1(mc, leaf); rc = mdb_cursor_get(&mc->mc_xcursor->mx_cursor, data, NULL, MDB_GET_CURRENT); } else { rc = mdb_node_read(mc->mc_txn, leaf, data); @@ -6869,7 +6867,6 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags) } } mc->mc_db->md_entries--; - mc->mc_flags |= C_DEL; return rc; } else { mc->mc_xcursor->mx_cursor.mc_flags &= ~C_INITIALIZED; @@ -8191,12 +8188,12 @@ mdb_cursor_del0(MDB_cursor *mc) if (m3 == mc || m3->mc_snum < mc->mc_snum) continue; if (m3->mc_pg[mc->mc_top] == mp) { - if (m3->mc_ki[mc->mc_top] >= ki) { + if (m3->mc_ki[mc->mc_top] == ki) { m3->mc_flags |= C_DEL; - if (m3->mc_ki[mc->mc_top] > ki) - m3->mc_ki[mc->mc_top]--; - else if (mc->mc_db->md_flags & MDB_DUPSORT) + if (mc->mc_db->md_flags & MDB_DUPSORT) m3->mc_xcursor->mx_cursor.mc_flags &= ~C_INITIALIZED; + } else if (m3->mc_ki[mc->mc_top] > ki) { + m3->mc_ki[mc->mc_top]--; } if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); From 00aae125bea7bc0af11d08cf32b50a2bb1757143 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 24 Nov 2015 15:09:49 +0000 Subject: [PATCH 12/16] ITS#8321 fix ambiguity in cursor_put fixup After delete/add of a node, other nodes may no longer be pointing at the data they intended. This can confuse subsequent fixups. --- libraries/liblmdb/mdb.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index b8c4355836..b87099e487 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -6683,22 +6683,28 @@ new_sub: } else { /* There is room already in this leaf page. */ rc = mdb_node_add(mc, mc->mc_ki[mc->mc_top], key, rdata, 0, nflags); - if (rc == 0 && insert_key) { + if (rc == 0) { /* Adjust other cursors pointing to mp */ MDB_cursor *m2, *m3; MDB_dbi dbi = mc->mc_dbi; unsigned i = mc->mc_top; MDB_page *mp = mc->mc_pg[i]; + int nkeys = NUMKEYS(mp); for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { if (mc->mc_flags & C_SUB) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; - if (m3 == mc || m3->mc_snum < mc->mc_snum) continue; - if (m3->mc_pg[i] == mp && m3->mc_ki[i] >= mc->mc_ki[i]) { + if (m3 == mc || m3->mc_snum < mc->mc_snum || m3->mc_pg[i] != mp) continue; + if (m3->mc_ki[i] >= mc->mc_ki[i] && insert_key) { m3->mc_ki[i]++; } + if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { + MDB_node *n2 = NODEPTR(mp, m3->mc_ki[i]); + if ((n2->mn_flags & (F_SUBDATA|F_DUPDATA)) == F_DUPDATA) + m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); + } } } } From 9ec8e188fb946eb0b2c541d3d4606d72b3c94392 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 24 Nov 2015 16:01:25 +0000 Subject: [PATCH 13/16] ITS#8323 --- libraries/liblmdb/CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/liblmdb/CHANGES b/libraries/liblmdb/CHANGES index 6322138a1f..1afd4ae306 100644 --- a/libraries/liblmdb/CHANGES +++ b/libraries/liblmdb/CHANGES @@ -20,6 +20,7 @@ LMDB 0.9.17 Release Engineering Fix ITS#8312 loose pages in nested txn Fix ITS#8313 mdb_rebalance dummy cursor Fix ITS#8315 dirty_room in nested txn + Fix ITS#8323 dirty_list in nested txn Fix ITS#8316 page_merge cursor tracking Fix ITS#8321 cursor tracking Fix ITS#8319 mdb_load error messages From 16b82752fc29082c62bbb311a0a98616516a2220 Mon Sep 17 00:00:00 2001 From: Heiko Becker Date: Thu, 11 Jun 2015 20:44:06 +0200 Subject: [PATCH 14/16] ITS#8168 Allow passing AR to make This is helpful when the ar executable is named differently, for example with an arch specific prefix. --- libraries/liblmdb/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/liblmdb/Makefile b/libraries/liblmdb/Makefile index 79752d2995..3fdc3a16ca 100644 --- a/libraries/liblmdb/Makefile +++ b/libraries/liblmdb/Makefile @@ -19,6 +19,7 @@ # read mdb.c before changing any of them. # CC = gcc +AR = ar W = -W -Wall -Wno-unused-parameter -Wbad-function-cast -Wuninitialized THREADS = -pthread OPT = -O2 -g @@ -54,7 +55,7 @@ test: all ./mtest && ./mdb_stat testdb liblmdb.a: mdb.o midl.o - ar rs $@ mdb.o midl.o + $(AR) rs $@ mdb.o midl.o liblmdb.so: mdb.lo midl.lo # $(CC) $(LDFLAGS) -pthread -shared -Wl,-Bsymbolic -o $@ mdb.o midl.o $(SOLIBS) From 376aea80db280fb8de379d1a95090be69c9df653 Mon Sep 17 00:00:00 2001 From: Heiko Becker Date: Thu, 11 Jun 2015 21:09:59 +0200 Subject: [PATCH 15/16] ITS#8169 Allow passing mandir to make install The motivation for this change is my distribution moving to a multiarch layout. While the architecture specific stuff (binaries, libraries, etc.) is installed under /usr/${host}/{bin,lib,...} architecture-independent data should still be installed to /usr/share/. --- libraries/liblmdb/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/liblmdb/Makefile b/libraries/liblmdb/Makefile index 3fdc3a16ca..dbb5d698fe 100644 --- a/libraries/liblmdb/Makefile +++ b/libraries/liblmdb/Makefile @@ -27,6 +27,7 @@ CFLAGS = $(THREADS) $(OPT) $(W) $(XCFLAGS) LDLIBS = SOLIBS = prefix = /usr/local +mandir = $(prefix)/man ######################################################################## @@ -45,7 +46,7 @@ install: $(ILIBS) $(IPROGS) $(IHDRS) for f in $(IPROGS); do cp $$f $(DESTDIR)$(prefix)/bin; done for f in $(ILIBS); do cp $$f $(DESTDIR)$(prefix)/lib; done for f in $(IHDRS); do cp $$f $(DESTDIR)$(prefix)/include; done - for f in $(IDOCS); do cp $$f $(DESTDIR)$(prefix)/man/man1; done + for f in $(IDOCS); do cp $$f $(DESTDIR)$(mandir)/man1; done clean: rm -rf $(PROGS) *.[ao] *.[ls]o *~ testdb From b617a3e804fde958c79909d13634dc1b199f9b32 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 24 Nov 2015 16:08:53 +0000 Subject: [PATCH 16/16] ITS#8168, 8169 --- libraries/liblmdb/CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/liblmdb/CHANGES b/libraries/liblmdb/CHANGES index 1afd4ae306..cc88d8c8e6 100644 --- a/libraries/liblmdb/CHANGES +++ b/libraries/liblmdb/CHANGES @@ -34,6 +34,8 @@ LMDB 0.9.17 Release Engineering Added ssize_t typedef for MSVC (ITS#8067) Use ANSI apis on Windows (ITS#8069) Use O_SYNC if O_DSYNC,MDB_DSYNC are not defined (ITS#7209) + Allow passing AR to make (ITS#8168) + Allow passing mandir to make install (ITS#8169) LMDB 0.9.16 Release (2015/08/14) Fix cursor EOF bug (ITS#8190)