Issue 8908 - LMDB Documentation for MDB_XXX_MULTIPLE
Summary: LMDB Documentation for MDB_XXX_MULTIPLE
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: documentation (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-08-27 01:07 UTC by karl@waclawek.net
Modified: 2018-12-19 17:18 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description karl@waclawek.net 2018-08-27 01:07:51 UTC
Full_Name: Karl Waclawek
Version: LMDB 0.9.22
OS: Windows 10
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (2607:fea8:7a80:814:3ca9:e8f6:801c:d6f8)


The documentation in lmdb.h for MDB_GET_MULTIPLE, MDB_NEXT_MULTIPLE and
MDB_PREV_MULTIPLE seems to have two issues:

1) The documentation indicates that both, the key and data, are returned, but in
reality only the data is returned.

2) The documentation states that MDB_GET_MULTIPLE moves the cursor. This does
not seem to be true.
Comment 1 Howard Chu 2018-08-29 00:26:46 UTC
> Full_Name: Karl Waclawek
> Version: LMDB 0.9.22
> OS: Windows 10
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (2607:fea8:7a80:814:3ca9:e8f6:801c:d6f8)
> 
> 
> The documentation in lmdb.h for MDB_GET_MULTIPLE, MDB_NEXT_MULTIPLE and
> MDB_PREV_MULTIPLE seems to have two issues:
> 
> 1) The documentation indicates that both, the key and data, are returned, but
in
> reality only the data is returned.

Looks like you're right. Since these are DUPs the key would be the same
every time so there's no need to return it on each call.
Doc fixed in git mdb.master.

> 2) The documentation states that MDB_GET_MULTIPLE moves the cursor. This does
> not seem to be true.

The doc is correct here. The cursor is advanced far enough that a
MDB_NEXT_MULTIPLE will return the following data, as opposed to just
returning the same data again.
Comment 2 Howard Chu 2018-08-29 00:27:13 UTC
changed notes
changed state Open to Test
moved from Incoming to Documentation
Comment 3 karl@waclawek.net 2018-08-29 13:21:50 UTC
As far as point 2 is concerned I was basing it on this piece of code, where
it looks like MDB_GET_MULTIPLE just checks some flags and then goes to the
fetchm label where the code does nothing but retrieve data:

case MDB_GET_MULTIPLE:
if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) {
rc = EINVAL;
break;
}
if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
rc = MDB_INCOMPATIBLE;
break;
}
rc = MDB_SUCCESS;
if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) ||
(mc->mc_xcursor->mx_cursor.mc_flags & C_EOF))
break;
goto fetchm;
case MDB_NEXT_MULTIPLE:
if (data == NULL) {
rc = EINVAL;
break;
}
if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
rc = MDB_INCOMPATIBLE;
break;
}
rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP);
if (rc == MDB_SUCCESS) {
if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) {
MDB_cursor *mx;
fetchm:
mx = &mc->mc_xcursor->mx_cursor;
data->mv_size = NUMKEYS(mx->mc_pg[mx->mc_top]) *
mx->mc_db->md_pad;
data->mv_data = METADATA(mx->mc_pg[mx->mc_top]);
mx->mc_ki[mx->mc_top] = NUMKEYS(mx->mc_pg[mx->mc_top])-1;
} else {
rc = MDB_NOTFOUND;
}
}
break;


On Tue, Aug 28, 2018 at 8:26 PM Howard Chu <openldap-its@openldap.org>
wrote:

> > Full_Name: Karl Waclawek
> > Version: LMDB 0.9.22
> > OS: Windows 10
> > URL: ftp://ftp.openldap.org/incoming/
> > Submission from: (NULL) (2607:fea8:7a80:814:3ca9:e8f6:801c:d6f8)
> >
> >
> > The documentation in lmdb.h for MDB_GET_MULTIPLE, MDB_NEXT_MULTIPLE and
> > MDB_PREV_MULTIPLE seems to have two issues:
> >
> > 1) The documentation indicates that both, the key and data, are
> returned, but
> in
> > reality only the data is returned.
>
> Looks like you're right. Since these are DUPs the key would be the same
> every time so there's no need to return it on each call.
> Doc fixed in git mdb.master.
>
> > 2) The documentation states that MDB_GET_MULTIPLE moves the cursor. This
> does
> > not seem to be true.
>
> The doc is correct here. The cursor is advanced far enough that a
> MDB_NEXT_MULTIPLE will return the following data, as opposed to just
> returning the same data again.
>
Comment 4 Howard Chu 2018-08-29 16:05:07 UTC
karl@waclawek.net wrote:
> --00000000000018b43a057492d87f
> Content-Type: text/plain; charset="UTF-8"
> 
> As far as point 2 is concerned I was basing it on this piece of code, where
> it looks like MDB_GET_MULTIPLE just checks some flags and then goes to the
> fetchm label where the code does nothing but retrieve data:

You're not reading the code correctly. See below.
> 
> case MDB_GET_MULTIPLE:
> if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) {
> rc = EINVAL;
> break;
> }
> if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
> rc = MDB_INCOMPATIBLE;
> break;
> }
> rc = MDB_SUCCESS;
> if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) ||
> (mc->mc_xcursor->mx_cursor.mc_flags & C_EOF))
> break;
> goto fetchm;
> case MDB_NEXT_MULTIPLE:
> if (data == NULL) {
> rc = EINVAL;
> break;
> }
> if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
> rc = MDB_INCOMPATIBLE;
> break;
> }
> rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP);
> if (rc == MDB_SUCCESS) {
> if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) {
> MDB_cursor *mx;
> fetchm:
> mx = &mc->mc_xcursor->mx_cursor;
> data->mv_size = NUMKEYS(mx->mc_pg[mx->mc_top]) *
> mx->mc_db->md_pad;
> data->mv_data = METADATA(mx->mc_pg[mx->mc_top]);
> mx->mc_ki[mx->mc_top] = NUMKEYS(mx->mc_pg[mx->mc_top])-1;

^^^ this line advances the cursor.

> } else {
> rc = MDB_NOTFOUND;
> }
> }
> break;
> 
> 
> On Tue, Aug 28, 2018 at 8:26 PM Howard Chu <openldap-its@openldap.org>
> wrote:
> 
>>> Full_Name: Karl Waclawek
>>> Version: LMDB 0.9.22
>>> OS: Windows 10
>>> URL: ftp://ftp.openldap.org/incoming/
>>> Submission from: (NULL) (2607:fea8:7a80:814:3ca9:e8f6:801c:d6f8)
>>>
>>>
>>> The documentation in lmdb.h for MDB_GET_MULTIPLE, MDB_NEXT_MULTIPLE and
>>> MDB_PREV_MULTIPLE seems to have two issues:
>>>
>>> 1) The documentation indicates that both, the key and data, are
>> returned, but
>> in
>>> reality only the data is returned.
>>
>> Looks like you're right. Since these are DUPs the key would be the same
>> every time so there's no need to return it on each call.
>> Doc fixed in git mdb.master.
>>
>>> 2) The documentation states that MDB_GET_MULTIPLE moves the cursor. This
>> does
>>> not seem to be true.
>>
>> The doc is correct here. The cursor is advanced far enough that a
>> MDB_NEXT_MULTIPLE will return the following data, as opposed to just
>> returning the same data again.
>>
> 



-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 5 karl@waclawek.net 2018-08-29 16:25:26 UTC
Thanks!

On Wed, Aug 29, 2018, 12:05 Howard Chu, <hyc@symas.com> wrote:

> karl@waclawek.net wrote:
> > --00000000000018b43a057492d87f
> > Content-Type: text/plain; charset="UTF-8"
> >
> > As far as point 2 is concerned I was basing it on this piece of code,
> where
> > it looks like MDB_GET_MULTIPLE just checks some flags and then goes to
> the
> > fetchm label where the code does nothing but retrieve data:
>
> You're not reading the code correctly. See below.
> >
> > case MDB_GET_MULTIPLE:
> > if (data == NULL || !(mc->mc_flags & C_INITIALIZED)) {
> > rc = EINVAL;
> > break;
> > }
> > if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
> > rc = MDB_INCOMPATIBLE;
> > break;
> > }
> > rc = MDB_SUCCESS;
> > if (!(mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) ||
> > (mc->mc_xcursor->mx_cursor.mc_flags & C_EOF))
> > break;
> > goto fetchm;
> > case MDB_NEXT_MULTIPLE:
> > if (data == NULL) {
> > rc = EINVAL;
> > break;
> > }
> > if (!(mc->mc_db->md_flags & MDB_DUPFIXED)) {
> > rc = MDB_INCOMPATIBLE;
> > break;
> > }
> > rc = mdb_cursor_next(mc, key, data, MDB_NEXT_DUP);
> > if (rc == MDB_SUCCESS) {
> > if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) {
> > MDB_cursor *mx;
> > fetchm:
> > mx = &mc->mc_xcursor->mx_cursor;
> > data->mv_size = NUMKEYS(mx->mc_pg[mx->mc_top]) *
> > mx->mc_db->md_pad;
> > data->mv_data = METADATA(mx->mc_pg[mx->mc_top]);
> > mx->mc_ki[mx->mc_top] = NUMKEYS(mx->mc_pg[mx->mc_top])-1;
>
> ^^^ this line advances the cursor.
>
> > } else {
> > rc = MDB_NOTFOUND;
> > }
> > }
> > break;
> >
> >
> > On Tue, Aug 28, 2018 at 8:26 PM Howard Chu <openldap-its@openldap.org>
> > wrote:
> >
> >>> Full_Name: Karl Waclawek
> >>> Version: LMDB 0.9.22
> >>> OS: Windows 10
> >>> URL: ftp://ftp.openldap.org/incoming/
> >>> Submission from: (NULL) (2607:fea8:7a80:814:3ca9:e8f6:801c:d6f8)
> >>>
> >>>
> >>> The documentation in lmdb.h for MDB_GET_MULTIPLE, MDB_NEXT_MULTIPLE and
> >>> MDB_PREV_MULTIPLE seems to have two issues:
> >>>
> >>> 1) The documentation indicates that both, the key and data, are
> >> returned, but
> >> in
> >>> reality only the data is returned.
> >>
> >> Looks like you're right. Since these are DUPs the key would be the same
> >> every time so there's no need to return it on each call.
> >> Doc fixed in git mdb.master.
> >>
> >>> 2) The documentation states that MDB_GET_MULTIPLE moves the cursor.
> This
> >> does
> >>> not seem to be true.
> >>
> >> The doc is correct here. The cursor is advanced far enough that a
> >> MDB_NEXT_MULTIPLE will return the following data, as opposed to just
> >> returning the same data again.
> >>
> >
>
>
>
> --
>    -- Howard Chu
>    CTO, Symas Corp.           http://www.symas.com
>    Director, Highland Sun     http://highlandsun.com/hyc/
>    Chief Architect, OpenLDAP  http://www.openldap.org/project/
>
Comment 6 OpenLDAP project 2018-12-19 17:18:06 UTC
fixed in mdb.master
fixed in mdb.re09 (0.9.23)
Comment 7 Quanah Gibson-Mount 2018-12-19 17:18:06 UTC
changed notes
changed state Test to Closed