diff --git a/libraries/liblmdb/CHANGES b/libraries/liblmdb/CHANGES
index bc39d82ab5..a6304660bb 100644
--- a/libraries/liblmdb/CHANGES
+++ b/libraries/liblmdb/CHANGES
@@ -1,5 +1,12 @@
LMDB 0.9 Change Log
+LMDB 0.9.17 Release Engineering
+ Fix ITS#7377 catch calloc failure
+ Fix ITS#8237 regression from ITS#7589
+ Fix ITS#8221 MDB_PAGE_FULL on delete/rebalance
+ Build
+ Create install dirs if needed (ITS#8256)
+
LMDB 0.9.16 Release (2015/08/14)
Fix cursor EOF bug (ITS#8190)
Fix handling of subDB records (ITS#8181)
diff --git a/libraries/liblmdb/Makefile b/libraries/liblmdb/Makefile
index 2d0983eff0..62b52a9ad1 100644
--- a/libraries/liblmdb/Makefile
+++ b/libraries/liblmdb/Makefile
@@ -36,6 +36,10 @@ PROGS = $(IPROGS) mtest mtest2 mtest3 mtest4 mtest5
all: $(ILIBS) $(PROGS)
install: $(ILIBS) $(IPROGS) $(IHDRS)
+ mkdir -p $(DESTDIR)$(prefix)/bin
+ mkdir -p $(DESTDIR)$(prefix)/lib
+ mkdir -p $(DESTDIR)$(prefix)/include
+ mkdir -p $(DESTDIR)$(prefix)/man/man1
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
diff --git a/libraries/liblmdb/lmdb.h b/libraries/liblmdb/lmdb.h
index 762dba2ec2..c5e5c9bf12 100644
--- a/libraries/liblmdb/lmdb.h
+++ b/libraries/liblmdb/lmdb.h
@@ -1280,7 +1280,8 @@ int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data);
* the next update operation or the transaction ends. This saves
* an extra memcpy if the data is being generated later.
* LMDB does nothing else with this memory, the caller is expected
- * to modify all of the space requested.
+ * to modify all of the space requested. This flag must not be
+ * specified if the database was opened with #MDB_DUPSORT.
*
#MDB_APPEND - append the given key/data pair to the end of the
* database. This option allows fast bulk loading when keys are
* already known to be in the correct order. Loading unsorted keys
@@ -1437,12 +1438,13 @@ int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
* #MDB_RESERVE - reserve space for data of the given size, but
* don't copy the given data. Instead, return a pointer to the
* reserved space, which the caller can fill in later. This saves
- * an extra memcpy if the data is being generated later.
+ * an extra memcpy if the data is being generated later. This flag
+ * must not be specified if the database was opened with #MDB_DUPSORT.
* #MDB_APPEND - append the given key/data pair to the end of the
* database. No key comparisons are performed. This option allows
* fast bulk loading when keys are already known to be in the
* correct order. Loading unsorted keys with this flag will cause
- * data corruption.
+ * a #MDB_KEYEXIST error.
* #MDB_APPENDDUP - as above, but for sorted dup data.
* #MDB_MULTIPLE - store multiple contiguous data elements in a
* single request. This flag may only be specified if the database
diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c
index b5d59bcdb1..50d359ebb0 100644
--- a/libraries/liblmdb/mdb.c
+++ b/libraries/liblmdb/mdb.c
@@ -3553,6 +3553,9 @@ mdb_env_init_meta(MDB_env *env, MDB_meta *meta)
mdb_env_init_meta0(env, meta);
p = calloc(2, psize);
+ if (!p)
+ return ENOMEM;
+
p->mp_pgno = 0;
p->mp_flags = P_META;
*(MDB_meta *)METADATA(p) = *meta;
@@ -7682,17 +7685,23 @@ mdb_rebalance(MDB_cursor *mc)
{
MDB_node *node;
int rc;
- unsigned int ptop, minkeys;
+ unsigned int ptop, minkeys, thresh;
MDB_cursor mn;
indx_t oldki;
- minkeys = 1 + (IS_BRANCH(mc->mc_pg[mc->mc_top]));
+ if (IS_BRANCH(mc->mc_pg[mc->mc_top])) {
+ minkeys = 1;
+ thresh = 1;
+ } else {
+ minkeys = 2;
+ thresh = FILL_THRESHOLD;
+ }
DPRINTF(("rebalancing %s page %"Z"u (has %u keys, %.1f%% full)",
IS_LEAF(mc->mc_pg[mc->mc_top]) ? "leaf" : "branch",
mdb_dbg_pgno(mc->mc_pg[mc->mc_top]), NUMKEYS(mc->mc_pg[mc->mc_top]),
(float)PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) / 10));
- if (PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) >= FILL_THRESHOLD &&
+ if (PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) >= thresh &&
NUMKEYS(mc->mc_pg[mc->mc_top]) >= minkeys) {
DPRINTF(("no need to rebalance page %"Z"u, above fill threshold",
mdb_dbg_pgno(mc->mc_pg[mc->mc_top])));
@@ -7826,8 +7835,7 @@ mdb_rebalance(MDB_cursor *mc)
* move one key from it. Otherwise we should try to merge them.
* (A branch page must never have less than 2 keys.)
*/
- minkeys = 1 + (IS_BRANCH(mn.mc_pg[mn.mc_top]));
- if (PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) >= FILL_THRESHOLD && NUMKEYS(mn.mc_pg[mn.mc_top]) > minkeys) {
+ if (PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) >= thresh && NUMKEYS(mn.mc_pg[mn.mc_top]) > minkeys) {
rc = mdb_node_move(&mn, mc);
if (mc->mc_ki[ptop]) {
oldki++;
@@ -8164,7 +8172,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
psize = 0;
if (newindx <= split_indx || newindx >= nkeys) {
i = 0; j = 1;
- k = newindx >= nkeys ? nkeys : split_indx+2;
+ k = newindx >= nkeys ? nkeys : split_indx+1+IS_LEAF(mp);
} else {
i = nkeys; j = -1;
k = split_indx-1;