From d8b459808520027019987d19c79250cbf737f2c3 Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Sat, 3 Mar 2012 09:49:20 +0100 Subject: [PATCH 1/4] ITS#7191 Fix mdb_xcursor_init1() unaligned access --- libraries/libmdb/mdb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/libmdb/mdb.c b/libraries/libmdb/mdb.c index f028ecb286..2a1cbb229e 100644 --- a/libraries/libmdb/mdb.c +++ b/libraries/libmdb/mdb.c @@ -4701,8 +4701,7 @@ mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node) MDB_xcursor *mx = mc->mc_xcursor; if (node->mn_flags & F_SUBDATA) { - MDB_db *db = NODEDATA(node); - mx->mx_db = *db; + memcpy(&mx->mx_db, NODEDATA(node), sizeof(MDB_db)); mx->mx_cursor.mc_snum = 0; mx->mx_cursor.mc_flags = C_SUB; } else { From e1b88d93ac8812635785dcc3f87ea015f454e022 Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Sat, 3 Mar 2012 09:52:33 +0100 Subject: [PATCH 2/4] Remove development file libmdb/make.sh --- libraries/libmdb/make.sh | 9 --------- 1 file changed, 9 deletions(-) delete mode 100755 libraries/libmdb/make.sh diff --git a/libraries/libmdb/make.sh b/libraries/libmdb/make.sh deleted file mode 100755 index 9b5aff2136..0000000000 --- a/libraries/libmdb/make.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -warning_filter() { - egrep -v ': In function .*:$|: warning: (ISO C99 requires rest arguments to be used|format .*%p.* has type .*struct MDB_.*\*)' -} - -exit `{ - { XCFLAGS="-std=c99 -pedantic" make "$@" 2>&1; echo $? >&3; } | - warning_filter >&2 -} 3>&1` From d50d57ed63a4fd29d90da3b7de9cc105fff63a3e Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Sun, 25 Sep 2011 23:36:49 +0200 Subject: [PATCH 3/4] Fix libmdb comments --- libraries/libmdb/mdb.c | 8 ++++---- libraries/libmdb/mdb.h | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/libmdb/mdb.c b/libraries/libmdb/mdb.c index 2a1cbb229e..a3398e19bc 100644 --- a/libraries/libmdb/mdb.c +++ b/libraries/libmdb/mdb.c @@ -330,7 +330,7 @@ typedef ID txnid_t; #endif /** @defgroup lazylock Lazy Locking - * Macros for locks that are't actually needed. + * Macros for locks that aren't actually needed. * The DB view is always consistent because all writes are wrapped in * the wmutex. Finer-grained locks aren't necessary. * @{ @@ -492,7 +492,7 @@ typedef struct MDB_reader { * unlikely. If a collision occurs, the results are unpredictable. */ typedef struct MDB_txbody { - /** Stamp identifying this as an MDB lock file. It must be set + /** Stamp identifying this as an MDB file. It must be set * to #MDB_MAGIC. */ uint32_t mtb_magic; /** Version number of this lock file. Must be set to #MDB_VERSION. */ @@ -748,7 +748,7 @@ typedef struct MDB_db { /** Meta page content. */ typedef struct MDB_meta { - /** Stamp identifying this as an MDB data file. It must be set + /** Stamp identifying this as an MDB file. It must be set * to #MDB_MAGIC. */ uint32_t mm_magic; /** Version number of this lock file. Must be set to #MDB_VERSION. */ @@ -857,7 +857,7 @@ struct MDB_cursor { /** The @ref mt_dbflag for this database */ unsigned char *mc_dbflag; unsigned short mc_snum; /**< number of pushed pages */ - unsigned short mc_top; /**< index of top page, mc_snum-1 */ + unsigned short mc_top; /**< index of top page, normally mc_snum-1 */ /** @defgroup mdb_cursor Cursor Flags * @ingroup internal * Cursor state flags. diff --git a/libraries/libmdb/mdb.h b/libraries/libmdb/mdb.h index 5682c8f868..6017ef58fa 100644 --- a/libraries/libmdb/mdb.h +++ b/libraries/libmdb/mdb.h @@ -432,7 +432,7 @@ int mdb_env_get_path(MDB_env *env, const char **path); * The size should be a multiple of the OS page size. The default is * 10485760 bytes. The size of the memory map is also the maximum size * of the database. The value should be chosen as large as possible, - * to accomodate future growth of the database. + * to accommodate future growth of the database. * This function may only be called after #mdb_env_create() and before #mdb_env_open(). * @param[in] env An environment handle returned by #mdb_env_create() * @param[in] size The size in bytes @@ -583,7 +583,7 @@ int mdb_txn_renew(MDB_txn *txn); * a read-only transaction. * @param[in] txn A transaction handle returned by #mdb_txn_begin() * @param[in] name The name of the database to open. If only a single - * database is needed in the enviroment, this value may be NULL. + * database is needed in the environment, this value may be NULL. * @param[in] flags Special options for this database. This parameter * must be set to 0 or by bitwise OR'ing together one or more of the * values described here. @@ -667,7 +667,7 @@ int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del); * * The comparison function is called whenever it is necessary to compare a * key specified by the application with a key currently stored in the database. - * If no comparison function is specified, and no speAGAINcial key flags were specified + * If no comparison function is specified, and no special key flags were specified * with #mdb_open(), the keys are compared lexically, with shorter keys collating * before longer keys. * @warning This function must be called before any data access functions are used, @@ -797,7 +797,7 @@ int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data); * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    - *
  • EACCESS - an attempt was made to write in a read-only transaction. + *
  • EACCES - an attempt was made to write in a read-only transaction. *
  • EINVAL - an invalid parameter was specified. *
  • ENOMEM - the database is full, see #mdb_env_set_mapsize(). *
@@ -823,7 +823,7 @@ int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, * @return A non-zero error value on failure and 0 on success. Some possible * errors are: *
    - *
  • EACCESS - an attempt was made to write in a read-only transaction. + *
  • EACCES - an attempt was made to write in a read-only transaction. *
  • EINVAL - an invalid parameter was specified. *
*/ From 7bc62c512824c0d54cc6885ea876c2764510eca2 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 6 Mar 2012 22:12:21 -0800 Subject: [PATCH 4/4] ITS#7190 fix merging of branch pages in deletes --- libraries/libmdb/mdb.c | 86 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 12 deletions(-) diff --git a/libraries/libmdb/mdb.c b/libraries/libmdb/mdb.c index a3398e19bc..1d13643195 100644 --- a/libraries/libmdb/mdb.c +++ b/libraries/libmdb/mdb.c @@ -1061,6 +1061,7 @@ mdb_dkey(MDB_val *key, char *buf) * printable characters, print it as-is instead of converting to hex. */ #if 1 + buf[0] = '\0'; for (i=0; imv_size; i++) ptr += sprintf(ptr, "%02x", *c++); #else @@ -1068,6 +1069,25 @@ mdb_dkey(MDB_val *key, char *buf) #endif return buf; } + +/** Display all the keys in the page. */ +static void +mdb_page_keys(MDB_page *mp) +{ + MDB_node *node; + unsigned int i, nkeys; + MDB_val key; + DKBUF; + + nkeys = NUMKEYS(mp); + DPRINTF("numkeys %d", nkeys); + for (i=0; imn_ksize; + key.mv_data = node->mn_data; + DPRINTF("key %d: %s", i, DKEY(&key)); + } +} #endif int @@ -4868,11 +4888,19 @@ mdb_update_key(MDB_page *mp, indx_t indx, MDB_val *key) node = NODEPTR(mp, indx); ptr = mp->mp_ptrs[indx]; - DPRINTF("update key %u (ofs %u) [%.*s] to [%s] on page %zu", - indx, ptr, - (int)node->mn_ksize, (char *)NODEKEY(node), - DKEY(key), - mp->mp_pgno); +#if MDB_DEBUG + { + MDB_val k2; + char kbuf2[(MAXKEYSIZE*2+1)]; + k2.mv_data = NODEKEY(node); + k2.mv_size = node->mn_ksize; + DPRINTF("update key %u (ofs %u) [%s] to [%s] on page %zu", + indx, ptr, + mdb_dkey(&k2, kbuf2), + DKEY(key), + mp->mp_pgno); + } +#endif delta = key->mv_size - node->mn_ksize; if (delta) { @@ -4896,7 +4924,8 @@ mdb_update_key(MDB_page *mp, indx_t indx, MDB_val *key) node->mn_ksize = key->mv_size; } - memcpy(NODEKEY(node), key->mv_data, key->mv_size); + if (key->mv_size) + memcpy(NODEKEY(node), key->mv_data, key->mv_size); return MDB_SUCCESS; } @@ -4909,6 +4938,9 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst) int rc; MDB_node *srcnode; MDB_val key, data; + pgno_t srcpg; + unsigned short flags; + DKBUF; /* Mark src and dst as dirty. */ @@ -4922,8 +4954,13 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst) key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], csrc->mc_ki[csrc->mc_top], key.mv_size); data.mv_size = 0; data.mv_data = NULL; + srcpg = 0; + flags = 0; } else { srcnode = NODEPTR(csrc->mc_pg[csrc->mc_top], csrc->mc_ki[csrc->mc_top]); + assert(!((long)srcnode&1)); + srcpg = NODEPGNO(srcnode); + flags = srcnode->mn_flags; if (csrc->mc_ki[csrc->mc_top] == 0 && IS_BRANCH(csrc->mc_pg[csrc->mc_top])) { unsigned int snum = csrc->mc_snum; MDB_node *s2; @@ -4941,7 +4978,21 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst) data.mv_size = NODEDSZ(srcnode); data.mv_data = NODEDATA(srcnode); } - DPRINTF("moving %s node %u [%s] on page %zu to node %u on page %zu", + 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; + MDB_val bkey; + /* must find the lowest key below dst */ + mdb_page_search_root(cdst, NULL, 0); + s2 = NODEPTR(cdst->mc_pg[cdst->mc_top], 0); + bkey.mv_size = NODEKSZ(s2); + bkey.mv_data = NODEKEY(s2); + cdst->mc_snum = snum--; + cdst->mc_top = snum; + rc = mdb_update_key(cdst->mc_pg[cdst->mc_top], 0, &bkey); + } + + XPRINTF("moving %s node %u [%s] on page %zu to node %u on page %zu", IS_LEAF(csrc->mc_pg[csrc->mc_top]) ? "leaf" : "branch", csrc->mc_ki[csrc->mc_top], DKEY(&key), @@ -4950,8 +5001,7 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst) /* Add the node to the destination page. */ - rc = mdb_node_add(cdst, cdst->mc_ki[cdst->mc_top], &key, &data, NODEPGNO(srcnode), - srcnode->mn_flags); + rc = mdb_node_add(cdst, cdst->mc_ki[cdst->mc_top], &key, &data, srcpg, flags); if (rc != MDB_SUCCESS) return rc; @@ -5074,9 +5124,21 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) } else { for (i = 0; i < NUMKEYS(csrc->mc_pg[csrc->mc_top]); i++, j++) { srcnode = NODEPTR(csrc->mc_pg[csrc->mc_top], i); + if (i == 0 && IS_BRANCH(csrc->mc_pg[csrc->mc_top])) { + unsigned int snum = csrc->mc_snum; + MDB_node *s2; + /* must find the lowest key below src */ + mdb_page_search_root(csrc, NULL, 0); + s2 = NODEPTR(csrc->mc_pg[csrc->mc_top], 0); + key.mv_size = NODEKSZ(s2); + key.mv_data = NODEKEY(s2); + csrc->mc_snum = snum--; + csrc->mc_top = snum; + } else { + key.mv_size = srcnode->mn_ksize; + key.mv_data = NODEKEY(srcnode); + } - key.mv_size = srcnode->mn_ksize; - key.mv_data = NODEKEY(srcnode); data.mv_size = NODEDSZ(srcnode); data.mv_data = NODEDATA(srcnode); rc = mdb_node_add(cdst, j, &key, &data, NODEPGNO(srcnode), srcnode->mn_flags); @@ -5112,11 +5174,11 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) dbi--; for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) { - if (m2 == csrc) continue; if (csrc->mc_flags & C_SUB) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; + if (m3 == csrc) continue; if (m3->mc_snum < csrc->mc_snum) continue; if (m3->mc_pg[csrc->mc_top] == csrc->mc_pg[csrc->mc_top]) { m3->mc_pg[csrc->mc_top] = mp;