[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: endless loop when adding 100000 entries (ITS#1939)



> Thanks for the detailed report. This error should not occur because the
> cursor->get operation should only return a (key,data) pair that matches
the
> current key. Could be a Berkeley DB bug, will require more investigation.

Not sure whether you are right.

The documentation of c_get( DB_LAST ) says that it sets the cursor to the
last key/data pair of the database and returns key and data. But the last
key must not equal to the current value of the key variable.

I think the question is whether the parameter "key" of bdb_idl_insert_key()
is a "in" parameter or an "in-out" parameter.

If it's only a "in" parameter, then the caller of bdb_idl_insert_key() can
expect that bdb_idl_insert_key() does not modify the "key" parameter (as
bdb_dn2id_add() did). In this case the problem is in the "if( count >=
BDB_IDL_DB_SIZE )" block in bdb_idl_insert_key() because it modifies "key".

If "key" it is a "in-out" parameter, then the problem is in bdb_dn2id_add()
because it expects that "key" will not be modified.

I assume that "key" in only a "in" parameter and tried to fix the problem by
using a new key variable  in the "if( count >= BDB_IDL_DB_SIZE )" block. Now
it seems to work fine. The endless loop is gone.

Please note that I have no idea what bdb_idl_insert_key() exactly does and
whether my change is correct or not.



if ( count >= BDB_IDL_DB_SIZE ) {
    /* No room, convert to a range */
     DBT key2;
     DBTzero( &key2 );

     lo = tmp;
     data.data = &hi;
     rc = cursor->c_get( cursor, &key2, &data, DB_LAST );

and all other uses of "key" in this block changed to "key2"
}

To make testing easier, I have changed BDB_IDL_DB_SIZE to ((1<<3)-2) and
BDB_IDL_UM_SIZE to ((1<<4)-2).