Full_Name: Hallvard B Furuseth
Version: 2.4.35
OS: Linux x86_64
URL:
Submission from: (NULL) (2001:700:100:556::233)
Submitted by: hallvard
Nodes of size MDB_env.me_nodemax-1 do not go in overflow pages,
but are too big for two of them to fit in the same page. Because:
- LEAFSIZE() does not round up to a factor of 2.
- MDB_env.me_nodemax is described as /** Max size of a node on a page */
(i.e. non-overflow page), but actually it's the minimum node size
which mdb_node_add() *will* put in an overflow page.
I don't see a reason to treat nodes of size 2k-1 and 2k differently
when seen "from the outside", so I think LEAFSIZE should have been
#define LEAFSIZE(k, d) ((1 + NODESIZE + (k)->mv_size + (d)->mv_size) & -2)
Also mdb_leaf_size():
sz = LEAFSIZE(key, data);
if (sz >= env->me_nodemax)
sz = (1 + NODESIZE + sizeof(pgno_t) + key->mv_size) & -2;
return sz + sizeof(indx_t);
and a corresponding fix in mdb_node_add().
Those changes crash test001. I don't know what else would need
fixing. Subpage sizes for one thing.
OTOH if you add a bunch of slightly smaller nodes, mdb will put
most of them in separate pages anyway without MDB_APPEND. To keep
down rebalancing when adding nodes in the middle? Or is this
another bug? So I don't know if more than the me_nodemax doc a
fix. And maybe a rename to something which fits what it does.
...and also the doc of mdb_branch_size(). "Sizes are always
rounded up to an even number of bytes, to guarantee 2-byte
alignment" happens somewhere, but not in mdb_branch_size() which
happily returns uneven sizes. But it works fine since it's only
used as SIZELEFT()<mdb_branch_size() where SIZELEFT() does return
an even size. Rounding branch_size up would make no difference.