mdbx: always copy the rest of page (MDB_RESERVE case).

Change-Id: Iebc406767bee98a85ab6efec887ed698ffe59066

> On 30. mars 2016 19:25, Леонид Юрьев wrote:
>
> Why mdb_cursor_put() doesn't copy the rest of page in case MDB_RESERVE?
>
> In other words - why we should copy or not copy an end of page in
> dependence from MDB_RESERVE?

2016-03-30 19:46 GMT+03:00 Howard Chu <hyc@symas.com>:

That logic is backwards because I was preserving existing behavior,
i.e. make the page - including unused portions - look the same with
put() in the child txn as put() in the parent.  So with MDB_RESERVE
the entire page must be copied in case the user peeks at it before
writing to it.  Without MDB_RESERVE, the initial part of the page
body need not be copied since LMDB is about to overwrite it.

I'll comment that, unless that code should just go away.  Don't know
if this is the best behavior or it was just easier to code it than
to decide whether to cater to such obscure user behavior.  But
people do come up with special things do do about overflow pages.
This commit is contained in:
Leo Yuriev 2016-03-30 00:28:24 +03:00
parent c17cff1d4e
commit 828a5d73ca

5
mdb.c
View File

@ -6866,7 +6866,7 @@ current:
* bother to try shrinking the page if the new data * bother to try shrinking the page if the new data
* is smaller than the overflow threshold. * is smaller than the overflow threshold.
*/ */
if (level > 1) { if (unlikely(level > 1)) {
/* It is writable only in a parent txn */ /* It is writable only in a parent txn */
size_t sz = (size_t) env->me_psize * ovpages, off; size_t sz = (size_t) env->me_psize * ovpages, off;
MDB_page *np = mdb_page_malloc(mc->mc_txn, ovpages); MDB_page *np = mdb_page_malloc(mc->mc_txn, ovpages);
@ -6878,7 +6878,8 @@ current:
/* Note - this page is already counted in parent's dirty_room */ /* Note - this page is already counted in parent's dirty_room */
rc2 = mdb_mid2l_insert(mc->mc_txn->mt_u.dirty_list, &id2); rc2 = mdb_mid2l_insert(mc->mc_txn->mt_u.dirty_list, &id2);
mdb_cassert(mc, rc2 == 0); mdb_cassert(mc, rc2 == 0);
if (!(flags & MDB_RESERVE)) { if (1 || /* LY: Hm, why we should do this differently in dependence from MDB_RESERVE? */
!(flags & MDB_RESERVE)) {
/* Copy end of page, adjusting alignment so /* Copy end of page, adjusting alignment so
* compiler may copy words instead of bytes. * compiler may copy words instead of bytes.
*/ */