[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openldap-bugs
Subject:    (ITS#7772) liblmdb sub-page growth when adding existing data
From:       h.b.furuseth () usit ! uio ! no
Date:       2013-12-23 18:39:39
Message-ID: 201312231839.rBNIddBY072118 () boole ! openldap ! org
[Download RAW message or body]

Full_Name: Hallvard B Furuseth
Version: mdb.master, 4c8f57615c5ca7b014c038e59c1045182e74f5ad
OS: Linux x86_64
URL: ftp://ftp.openldap.org/incoming/Hallvard-Furuseth-growth-131223.c
Submission from: (NULL) (81.191.45.35)
Submitted by: hallvard


A non-LEAF2 sub-page grows if you put() a data item which already
exists.  The space remains unused while the sub-page exists.
(A LEAF2 page grows reusable space, and only if it is full.)

Demo program enclosed.  Edit mdb.c to set mdb_debug=1 and build
with -DMDB_DEBUG.  Watch the 1st DPRINTF() in mdb_node_add():

bash$ ./a.out 2>&1 | perl -lne '/add to (.*) key size/ && print $1'
leaf page 2 index 0, data size 404    # node with 1st item
leaf page 2 index 0, data size 840    # convert to sub-page for 2nd item
leaf sub-page 2 index 0, data size 0
leaf sub-page 2 index 1, data size 0
leaf page 2 index 0, data size 1250   # space for re-adding 2nd item
leaf page 2 index 0, data size 1660   # space for re-adding 2nd item
leaf page 2 index 0, data size 48     # ...too big, moved to sub-DB.

Fix: lmdb could position cursor+xcursor fully before spill/touch,
with an MDB_GET_BOTH variant which returns different codes for "no
such key" and "no such data".  And position it before MDB_MULTIPLE
loops up.  The current comparisons to see if the data item exists,
go away.  Maybe mdb_cursor_put() gets split in several functions,
since much of the work in the recursive put()s will be unneeded.

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic