Merge remote branch 'origin/mdb.master'

This commit is contained in:
Howard Chu 2012-03-06 22:17:19 -08:00
commit 5ce2a2aee6
3 changed files with 84 additions and 32 deletions

View File

@ -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`

View File

@ -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.
@ -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; i<key->mv_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; i<nkeys; i++) {
node = NODEPTR(mp, i);
key.mv_size = node->mn_ksize;
key.mv_data = node->mn_data;
DPRINTF("key %d: %s", i, DKEY(&key));
}
}
#endif
int
@ -4701,8 +4721,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 {
@ -4869,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) {
@ -4897,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;
}
@ -4910,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. */
@ -4923,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;
@ -4942,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),
@ -4951,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;
@ -5075,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);
@ -5113,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;

View File

@ -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:
* <ul>
* <li>EACCESS - an attempt was made to write in a read-only transaction.
* <li>EACCES - an attempt was made to write in a read-only transaction.
* <li>EINVAL - an invalid parameter was specified.
* <li>ENOMEM - the database is full, see #mdb_env_set_mapsize().
* </ul>
@ -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:
* <ul>
* <li>EACCESS - an attempt was made to write in a read-only transaction.
* <li>EACCES - an attempt was made to write in a read-only transaction.
* <li>EINVAL - an invalid parameter was specified.
* </ul>
*/