+int bdb_tool_next_id(
+ BackendDB *be,
+ DB_TXN *tid,
+ Entry *e,
+ struct berval *text,
+ int hole )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+ struct berval dn = e->e_nname;
+ struct berval pdn;
+ int rc;
+
+ rc = bdb_dn2id( be, tid, &dn, &e->e_id, 0 );
+ if ( rc == DB_NOTFOUND ) {
+ if ( be_issuffix( be, &dn ) ) {
+ pdn = slap_empty_bv;
+ } else {
+ dnParent( &dn, &pdn );
+ e->e_nname = pdn;
+ rc = bdb_tool_next_id( be, tid, e, text, 1 );
+ if ( rc ) {
+ return rc;
+ }
+ }
+ rc = bdb_next_id( be, tid, &e->e_id );
+ if ( rc ) {
+ snprintf( text->bv_val, text->bv_len,
+ "next_id failed: %s (%d)",
+ db_strerror(rc), rc );
+#ifdef NEW_LOGGING
+ LDAP_LOG ( TOOLS, ERR,
+ "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
+#endif
+ return rc;
+ }
+ e->e_nname = dn;
+ rc = bdb_dn2id_add( be, tid, &pdn, e );
+ if ( rc ) {
+ snprintf( text->bv_val, text->bv_len,
+ "dn2id_add failed: %s (%d)",
+ db_strerror(rc), rc );
+#ifdef NEW_LOGGING
+ LDAP_LOG ( TOOLS, ERR,
+ "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "=> bdb_tool_entry_put: %s\n", text->bv_val, 0, 0 );
+#endif
+ } else if ( hole ) {
+ if ( nholes == nhmax - 1 ) {
+ if ( holes == hbuf ) {
+ holes = ch_malloc( nhmax * sizeof(ID) * 2 );
+ AC_MEMCPY( holes, hbuf, sizeof(hbuf) );
+ } else {
+ holes = ch_realloc( holes, nhmax * sizeof(ID) * 2 );
+ }
+ nhmax *= 2;
+ }
+ ber_dupbv( &holes[nholes].dn, &dn );
+ holes[nholes++].id = e->e_id;
+ }
+ } else if ( !hole ) {
+ unsigned i;
+
+ for ( i=0; i<nholes; i++) {
+ if ( holes[i].id == e->e_id ) {
+ int j;
+ free(holes[i].dn.bv_val);
+ for (j=i;j<nholes;j++) holes[j] = holes[j+1];
+ holes[j].id = 0;
+ nholes--;
+ break;
+ } else if ( holes[i].id > e->e_id ) {
+ break;
+ }
+ }
+ }
+ return rc;
+}
+