From 9febe03eb595d72c1fe933b706559bf66789d1f0 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sat, 2 Aug 2014 10:33:35 -0700 Subject: [PATCH 1/5] More for MIPS Paranoia for 3630066843b7ca6b2cd12911d3e2fe3314cd4549 do the cacheflush before setting mti_txnid. --- libraries/liblmdb/mdb.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 96f5772903..16f5855615 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -3581,6 +3581,10 @@ fail: return rc; } done: + /* MIPS has cache coherency issues, this is a no-op everywhere else */ + if (!(env->me_flags & MDB_WRITEMAP)) { + CACHEFLUSH(env->me_map, txn->mt_next_pgno * env->me_psize, DCACHE); + } /* Memory ordering issues are irrelevant; since the entire writer * is wrapped by wmutex, all of these changes will become visible * after the wmutex is unlocked. Since the DB is multi-version, @@ -3590,11 +3594,6 @@ done: if (env->me_txns) env->me_txns->mti_txnid = txn->mt_txnid; - /* MIPS has cache coherency issues, this is a no-op everywhere else */ - if (!(env->me_flags & MDB_WRITEMAP)) { - CACHEFLUSH(env->me_map, txn->mt_next_pgno * env->me_psize, DCACHE); - } - return MDB_SUCCESS; } From f21f15e5a054546430e6acfa9d639f770184ecbc Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 4 Aug 2014 04:57:53 -0700 Subject: [PATCH 2/5] ITS#7793 update branch key if needed --- libraries/liblmdb/mdb.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 16f5855615..d8ac0406c6 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -6056,6 +6056,22 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data, return MDB_BAD_VALSIZE; ptr = LEAF2KEY(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top], ksize); memcpy(ptr, key->mv_data, ksize); +fix_parent: + /* if overwriting slot 0 of leaf, need to + * update branch key if there is a parent page + */ + if (mc->mc_top && !mc->mc_ki[mc->mc_top]) { + unsigned short top = mc->mc_top; + mc->mc_top--; + /* slot 0 is always an empty key, needs no update */ + if (mc->mc_ki[mc->mc_top]) + rc2 = mdb_update_key(mc, key); + else + rc2 = MDB_SUCCESS; + mc->mc_top = top; + if (rc2) + return rc2; + } return MDB_SUCCESS; } @@ -6261,8 +6277,10 @@ current: data->mv_data = olddata.mv_data; else if (!(mc->mc_flags & C_SUB)) memcpy(olddata.mv_data, data->mv_data, data->mv_size); - else + else { memcpy(NODEKEY(leaf), key->mv_data, key->mv_size); + goto fix_parent; + } return MDB_SUCCESS; } mdb_node_del(mc, 0); From 9cf1749f7329a7c3f53f461aab776685602d7ff6 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 4 Aug 2014 05:13:29 -0700 Subject: [PATCH 3/5] ITS#7793 doc update, again --- libraries/liblmdb/lmdb.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/liblmdb/lmdb.h b/libraries/liblmdb/lmdb.h index a4c4bca621..11b46bfa48 100644 --- a/libraries/liblmdb/lmdb.h +++ b/libraries/liblmdb/lmdb.h @@ -1410,7 +1410,10 @@ int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, *
    *
  • #MDB_CURRENT - replace the item at the current cursor position. * The \b key parameter must still be provided, and must match it. - * So must \b data if using sorted duplicates (#MDB_DUPSORT). + * If using sorted duplicates (#MDB_DUPSORT) the data item must still + * sort into the same place. This is intended to be used when the + * new data is the same size as the old. Otherwise it will simply + * perform a delete of the old record followed by an insert. *
  • #MDB_NODUPDATA - enter the new key/data pair only if it does not * already appear in the database. This flag may only be specified * if the database was opened with #MDB_DUPSORT. The function will From ae0c9f484d4ac8530364b1681a1f1f56fbfea3af Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 4 Aug 2014 09:26:35 -0700 Subject: [PATCH 4/5] ITS#7793 more for branch key update --- libraries/liblmdb/mdb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index d8ac0406c6..dddfed1c66 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -6063,7 +6063,9 @@ fix_parent: if (mc->mc_top && !mc->mc_ki[mc->mc_top]) { unsigned short top = mc->mc_top; mc->mc_top--; - /* slot 0 is always an empty key, needs no update */ + /* slot 0 is always an empty key, find real slot */ + while (mc->mc_top && !mc->mc_ki[mc->mc_top]) + mc->mc_top--; if (mc->mc_ki[mc->mc_top]) rc2 = mdb_update_key(mc, key); else From 899b23f89dd9f0eeb795d0772c0a8cd046c84ec3 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 4 Aug 2014 11:40:24 -0700 Subject: [PATCH 5/5] More for MIPS Do a cacheflush after writing data pages, separate from meta's cacheflush --- libraries/liblmdb/mdb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index dddfed1c66..8b560ed32e 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -3110,6 +3110,12 @@ mdb_page_flush(MDB_txn *txn, int keep) #endif /* _WIN32 */ } + /* MIPS has cache coherency issues, this is a no-op everywhere else + * Note: for any size >= on-chip cache size, entire on-chip cache is + * flushed. + */ + CACHEFLUSH(env->me_map, txn->mt_next_pgno * env->me_psize, DCACHE); + for (i = keep; ++i <= pagecount; ) { dp = dl[i].mptr; /* This is a page we skipped above */ @@ -3583,7 +3589,7 @@ fail: done: /* MIPS has cache coherency issues, this is a no-op everywhere else */ if (!(env->me_flags & MDB_WRITEMAP)) { - CACHEFLUSH(env->me_map, txn->mt_next_pgno * env->me_psize, DCACHE); + CACHEFLUSH(env->me_map + off, len, DCACHE); } /* Memory ordering issues are irrelevant; since the entire writer * is wrapped by wmutex, all of these changes will become visible