lmdb: Set/clear mp_pad, md_pad (MDB_DUPFIXED data size).

mdb_xcursor_init1(): md_pad is only used when MDB_DUPFIXED.
mdb_page_split():    Copy mp_pad too. Used by mdb_page_list().

Change-Id: Ia35cba3a367c04929a34a5879abc968202086e89
This commit is contained in:
Hallvard Furuseth 2015-05-20 04:04:38 +02:00 committed by Leo Yuriev
parent 36be104097
commit bb7b923fdd

69
mdb.c
View File

@ -602,7 +602,7 @@ typedef struct MDB_page {
pgno_t p_pgno; /**< page number */
struct MDB_page *p_next; /**< for in-memory list of freed pages */
} mp_p;
uint16_t mp_pad;
uint16_t mp_ksize;
/** @defgroup mdb_page Page Flags
* @ingroup internal
* Flags for the page headers.
@ -786,7 +786,7 @@ typedef struct MDB_node {
/** Information about a single database in the environment. */
typedef struct MDB_db {
uint32_t md_psize; /**< also ksize for LEAF2 pages */
uint32_t md_xsize; /**< also ksize for LEAF2 pages */
uint16_t md_flags; /**< @ref mdb_dbi_open */
uint16_t md_depth; /**< depth of this tree */
pgno_t md_branch_pages; /**< number of internal pages */
@ -821,7 +821,7 @@ typedef struct MDB_meta {
size_t mm_mapsize; /**< size of mmap region */
MDB_db mm_dbs[2]; /**< first is free space, 2nd is main db */
/** The size of pages used in this DB */
#define mm_psize mm_dbs[0].md_psize
#define mm_psize mm_dbs[0].md_xsize
/** Any persistent environment flags. @ref mdb_env */
#define mm_flags mm_dbs[0].md_flags
pgno_t mm_last_pg; /**< last used page in file */
@ -1427,7 +1427,7 @@ mdb_page_list(MDB_page *mp)
for (i=0; i<nkeys; i++) {
if (IS_LEAF2(mp)) { /* LEAF2 pages have no mp_ptrs[] or node headers */
key.mv_size = nsize = mp->mp_pad;
key.mv_size = nsize = mp->mp_ksize;
key.mv_data = LEAF2KEY(mp, i, nsize);
total += nsize;
mdb_print("key %d: nsize %d, %s\n", i, nsize, DKEY(&key));
@ -2333,7 +2333,7 @@ search_done:
VALGRIND_MAKE_MEM_UNDEFINED(np, env->me_psize * num);
np->mp_pgno = pgno;
np->mp_pad = 0;
np->mp_ksize = 0;
mdb_page_dirty(txn, np);
*mp = np;
@ -4938,7 +4938,7 @@ mdb_node_search(MDB_cursor *mc, MDB_val *key, int *exactp)
cmp = mdb_cmp_int_a;
if (IS_LEAF2(mp)) {
nodekey.mv_size = mc->mc_db->md_psize;
nodekey.mv_size = mc->mc_db->md_xsize;
node = NODEPTR(mp, 0); /* fake */
while (low <= high) {
i = (low + high) >> 1;
@ -5518,7 +5518,7 @@ skip:
mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]);
if (IS_LEAF2(mp)) {
key->mv_size = mc->mc_db->md_psize;
key->mv_size = mc->mc_db->md_xsize;
key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
return MDB_SUCCESS;
}
@ -5596,7 +5596,7 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]);
if (IS_LEAF2(mp)) {
key->mv_size = mc->mc_db->md_psize;
key->mv_size = mc->mc_db->md_xsize;
key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
return MDB_SUCCESS;
}
@ -5655,7 +5655,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data,
return MDB_NOTFOUND;
}
if (mp->mp_flags & P_LEAF2) {
nodekey.mv_size = mc->mc_db->md_psize;
nodekey.mv_size = mc->mc_db->md_xsize;
nodekey.mv_data = LEAF2KEY(mp, 0, nodekey.mv_size);
} else {
leaf = NODEPTR(mp, 0);
@ -5765,7 +5765,7 @@ set1:
if (IS_LEAF2(mp)) {
if (op == MDB_SET_RANGE || op == MDB_SET_KEY) {
key->mv_size = mc->mc_db->md_psize;
key->mv_size = mc->mc_db->md_xsize;
key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
}
return MDB_SUCCESS;
@ -5842,7 +5842,7 @@ mdb_cursor_first(MDB_cursor *mc, MDB_val *key, MDB_val *data)
mc->mc_ki[mc->mc_top] = 0;
if (IS_LEAF2(mc->mc_pg[mc->mc_top])) {
key->mv_size = mc->mc_db->md_psize;
key->mv_size = mc->mc_db->md_xsize;
key->mv_data = LEAF2KEY(mc->mc_pg[mc->mc_top], 0, key->mv_size);
return MDB_SUCCESS;
}
@ -5887,7 +5887,7 @@ mdb_cursor_last(MDB_cursor *mc, MDB_val *key, MDB_val *data)
leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
if (IS_LEAF2(mc->mc_pg[mc->mc_top])) {
key->mv_size = mc->mc_db->md_psize;
key->mv_size = mc->mc_db->md_xsize;
key->mv_data = LEAF2KEY(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top], key->mv_size);
return MDB_SUCCESS;
}
@ -5936,7 +5936,7 @@ mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data,
}
rc = MDB_SUCCESS;
if (IS_LEAF2(mp)) {
key->mv_size = mc->mc_db->md_psize;
key->mv_size = mc->mc_db->md_xsize;
key->mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], key->mv_size);
} else {
MDB_node *leaf = NODEPTR(mp, mc->mc_ki[mc->mc_top]);
@ -6007,7 +6007,7 @@ mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data,
fetchm:
mx = &mc->mc_xcursor->mx_cursor;
data->mv_size = NUMKEYS(mx->mc_pg[mx->mc_top]) *
mx->mc_db->md_psize;
mx->mc_db->md_xsize;
data->mv_data = PAGEDATA(mx->mc_pg[mx->mc_top]);
mx->mc_ki[mx->mc_top] = NUMKEYS(mx->mc_pg[mx->mc_top])-1;
} else {
@ -6269,7 +6269,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
*/
fp_flags = P_LEAF|P_DIRTY;
fp = env->me_pbuf;
fp->mp_pad = data->mv_size; /* used if MDB_DUPFIXED */
fp->mp_ksize = data->mv_size; /* used if MDB_DUPFIXED */
fp->mp_lower = fp->mp_upper = (PAGEHDRSZ-PAGEBASE);
olddata.mv_size = PAGEHDRSZ;
goto prep_subDB;
@ -6278,7 +6278,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
/* there's only a key anyway, so this is a no-op */
if (IS_LEAF2(mc->mc_pg[mc->mc_top])) {
char *ptr;
unsigned ksize = mc->mc_db->md_psize;
unsigned ksize = mc->mc_db->md_xsize;
if (key->mv_size != ksize)
return MDB_BAD_VALSIZE;
ptr = LEAF2KEY(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top], ksize);
@ -6344,7 +6344,7 @@ more:
xdata.mv_size = PAGEHDRSZ + dkey.mv_size + data->mv_size;
if (mc->mc_db->md_flags & MDB_DUPFIXED) {
fp->mp_flags |= P_LEAF2;
fp->mp_pad = data->mv_size;
fp->mp_ksize = data->mv_size;
xdata.mv_size += 2 * data->mv_size; /* leave space for 2 more */
} else {
xdata.mv_size += 2 * (sizeof(indx_t) + NODESIZE) +
@ -6366,7 +6366,7 @@ more:
data->mv_size);
break;
}
offset = fp->mp_pad;
offset = fp->mp_ksize;
if (SIZELEFT(fp) < offset) {
offset *= 4; /* space for 4 more */
break;
@ -6389,12 +6389,12 @@ more:
prep_subDB:
if (mc->mc_db->md_flags & MDB_DUPFIXED) {
fp_flags |= P_LEAF2;
dummy.md_psize = fp->mp_pad;
dummy.md_xsize = fp->mp_ksize;
dummy.md_flags = MDB_DUPFIXED;
if (mc->mc_db->md_flags & MDB_INTEGERDUP)
dummy.md_flags |= MDB_INTEGERKEY;
} else {
dummy.md_psize = 0;
dummy.md_xsize = 0;
dummy.md_flags = 0;
}
dummy.md_depth = 1;
@ -6412,11 +6412,11 @@ prep_subDB:
}
if (mp != fp) {
mp->mp_flags = fp_flags | P_DIRTY;
mp->mp_pad = fp->mp_pad;
mp->mp_ksize = fp->mp_ksize;
mp->mp_lower = fp->mp_lower;
mp->mp_upper = fp->mp_upper + offset;
if (fp_flags & P_LEAF2) {
memcpy(PAGEDATA(mp), PAGEDATA(fp), NUMKEYS(fp) * fp->mp_pad);
memcpy(PAGEDATA(mp), PAGEDATA(fp), NUMKEYS(fp) * fp->mp_ksize);
} else {
memcpy((char *)mp + mp->mp_upper + PAGEBASE, (char *)fp + fp->mp_upper + PAGEBASE,
olddata.mv_size - fp->mp_upper - PAGEBASE);
@ -6846,7 +6846,7 @@ mdb_node_add(MDB_cursor *mc, indx_t indx,
if (IS_LEAF2(mp)) {
/* Move higher keys up one slot. */
int ksize = mc->mc_db->md_psize, dif;
int ksize = mc->mc_db->md_xsize, dif;
char *ptr = LEAF2KEY(mp, indx, ksize);
dif = NUMKEYS(mp) - indx;
if (dif > 0)
@ -7023,7 +7023,7 @@ mdb_node_shrink(MDB_page *mp, indx_t indx)
/* shift subpage upward */
if (IS_LEAF2(sp)) {
nsize = NUMKEYS(sp) * sp->mp_pad;
nsize = NUMKEYS(sp) * sp->mp_ksize;
if (nsize & 1)
return; /* do not make the node uneven-sized */
memmove(PAGEDATA(xp), PAGEDATA(sp), nsize);
@ -7036,7 +7036,7 @@ mdb_node_shrink(MDB_page *mp, indx_t indx)
xp->mp_upper = sp->mp_lower;
xp->mp_lower = sp->mp_lower;
xp->mp_flags = sp->mp_flags;
xp->mp_pad = sp->mp_pad;
xp->mp_ksize = sp->mp_ksize;
COPY_PGNO(xp->mp_pgno, mp->mp_pgno);
nsize = NODEDSZ(node) - delta;
@ -7104,7 +7104,7 @@ mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node)
mx->mx_cursor.mc_flags = C_SUB;
} else {
MDB_page *fp = NODEDATA(node);
mx->mx_db.md_psize = mc->mc_pg[mc->mc_top]->mp_pad;
mx->mx_db.md_xsize = 0;
mx->mx_db.md_flags = 0;
mx->mx_db.md_depth = 1;
mx->mx_db.md_branch_pages = 0;
@ -7119,7 +7119,7 @@ mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node)
mx->mx_cursor.mc_ki[0] = 0;
if (mc->mc_db->md_flags & MDB_DUPFIXED) {
mx->mx_db.md_flags = MDB_DUPFIXED;
mx->mx_db.md_psize = fp->mp_pad;
mx->mx_db.md_xsize = fp->mp_ksize;
if (mc->mc_db->md_flags & MDB_INTEGERDUP)
mx->mx_db.md_flags |= MDB_INTEGERKEY;
}
@ -7364,7 +7364,7 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst)
return rc;
if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) {
key.mv_size = csrc->mc_db->md_psize;
key.mv_size = csrc->mc_db->md_xsize;
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;
@ -7383,7 +7383,7 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst)
if (rc)
return rc;
if (IS_LEAF2(csrc->mc_pg[csrc->mc_top])) {
key.mv_size = csrc->mc_db->md_psize;
key.mv_size = csrc->mc_db->md_xsize;
key.mv_data = LEAF2KEY(csrc->mc_pg[csrc->mc_top], 0, key.mv_size);
} else {
s2 = NODEPTR(csrc->mc_pg[csrc->mc_top], 0);
@ -7409,7 +7409,7 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst)
if (rc)
return rc;
if (IS_LEAF2(mn.mc_pg[mn.mc_top])) {
bkey.mv_size = mn.mc_db->md_psize;
bkey.mv_size = mn.mc_db->md_xsize;
bkey.mv_data = LEAF2KEY(mn.mc_pg[mn.mc_top], 0, bkey.mv_size);
} else {
s2 = NODEPTR(mn.mc_pg[mn.mc_top], 0);
@ -7556,7 +7556,7 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst)
*/
j = nkeys = NUMKEYS(pdst);
if (IS_LEAF2(psrc)) {
key.mv_size = csrc->mc_db->md_psize;
key.mv_size = csrc->mc_db->md_xsize;
key.mv_data = PAGEDATA(psrc);
for (i = 0; i < NUMKEYS(psrc); i++, j++) {
rc = mdb_node_add(cdst, j, &key, NULL, 0, 0);
@ -7576,7 +7576,7 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst)
if (rc)
return rc;
if (IS_LEAF2(mn.mc_pg[mn.mc_top])) {
key.mv_size = mn.mc_db->md_psize;
key.mv_size = mn.mc_db->md_xsize;
key.mv_data = LEAF2KEY(mn.mc_pg[mn.mc_top], 0, key.mv_size);
} else {
s2 = NODEPTR(mn.mc_pg[mn.mc_top], 0);
@ -7879,7 +7879,7 @@ mdb_cursor_del0(MDB_cursor *mc)
unsigned nkeys;
ki = mc->mc_ki[mc->mc_top];
mdb_node_del(mc, mc->mc_db->md_psize);
mdb_node_del(mc, mc->mc_db->md_xsize);
mc->mc_db->md_entries--;
rc = mdb_rebalance(mc);
@ -8038,6 +8038,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
/* Create a right sibling. */
if ((rc = mdb_page_new(mc, mp->mp_flags, 1, &rp)))
return rc;
rp->mp_ksize = mp->mp_ksize;
mdb_debug("new right sibling: page %zu", rp->mp_pgno);
if (mc->mc_snum < 2) {
@ -8090,7 +8091,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
unsigned lsize, rsize, ksize;
/* Move half of the keys to the right sibling */
x = mc->mc_ki[mc->mc_top] - split_indx;
ksize = mc->mc_db->md_psize;
ksize = mc->mc_db->md_xsize;
split = LEAF2KEY(mp, split_indx, ksize);
rsize = (nkeys - split_indx) * ksize;
lsize = (nkeys - split_indx) * sizeof(indx_t);