+
+int
+idl_delete_key (
+ Backend *be,
+ DBCache *db,
+ Datum key,
+ ID id
+)
+{
+ Datum data;
+ ID_BLOCK *idl;
+ unsigned i;
+ int j, nids;
+
+ if ( (idl = idl_fetch_one( be, db, key ) ) == NULL )
+ {
+ /* It wasn't found. Hmm... */
+ return -1;
+ }
+
+ if ( ID_BLOCK_ALLIDS( idl ) ) {
+ idl_free( idl );
+ return 0;
+ }
+
+ if ( ! ID_BLOCK_INDIRECT( idl ) ) {
+ i = idl_find(idl, id);
+ if ( ID_BLOCK_ID(idl, i) == id ) {
+ if( --ID_BLOCK_NIDS(idl) == 0 ) {
+ ldbm_cache_delete( db, key );
+
+ } else {
+ AC_MEMCPY(
+ &ID_BLOCK_ID(idl, i),
+ &ID_BLOCK_ID(idl, i+1),
+ (ID_BLOCK_NIDS(idl)-i) * sizeof(ID) );
+
+ ID_BLOCK_ID(idl, ID_BLOCK_NIDS(idl)) = NOID;
+
+ idl_store( be, db, key, idl );
+ }
+
+ idl_free( idl );
+ return 0;
+ }
+ /* We didn't find the ID. Hmmm... */
+ idl_free( idl );
+ return -1;
+ }
+
+ /* We have to go through an indirect block and find the ID
+ in the list of IDL's
+ */
+ cont_alloc( &data, &key );
+#ifndef USE_INDIRECT_NIDS
+ for ( nids = 0; !ID_BLOCK_NOID(idl, nids); nids++ )
+ ; /* NULL */
+
+ for ( j = 0; j<nids; j++ )
+#else
+ nids = ID_BLOCK_NIDS(idl);
+ for ( j = idl_find(idl, id); j >= 0; j = -1) /* execute once */
+#endif
+ {
+ ID_BLOCK *tmp;
+ cont_id( &data, ID_BLOCK_ID(idl, j) );
+
+ if ( (tmp = idl_fetch_one( be, db, data )) == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( INDEX, INFO,
+ "idl_delete_key: idl_fetch_one returned NULL\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "idl_delete_key: idl_fetch of returned NULL\n", 0, 0, 0 );
+#endif
+
+ continue;
+ }
+ /*
+ Now try to find the ID in tmp
+ */
+
+ i = idl_find(tmp, id);
+ if ( ID_BLOCK_ID(tmp, i) == id )
+ {
+ AC_MEMCPY(
+ &ID_BLOCK_ID(tmp, i),
+ &ID_BLOCK_ID(tmp, i+1),
+ (ID_BLOCK_NIDS(tmp)-(i+1)) * sizeof(ID));
+ ID_BLOCK_ID(tmp, ID_BLOCK_NIDS(tmp)-1 ) = NOID;
+ ID_BLOCK_NIDS(tmp)--;
+
+ if ( ID_BLOCK_NIDS(tmp) ) {
+ idl_store ( be, db, data, tmp );
+
+ } else {
+ ldbm_cache_delete( db, data );
+ AC_MEMCPY(
+ &ID_BLOCK_ID(idl, j),
+ &ID_BLOCK_ID(idl, j+1),
+ (nids-(j+1)) * sizeof(ID));
+ ID_BLOCK_ID(idl, nids-1) = NOID;
+ nids--;
+#ifdef USE_INDIRECT_NIDS
+ ID_BLOCK_NIDS(idl)--;
+#endif
+ if ( ! nids )
+ ldbm_cache_delete( db, key );
+ else
+ idl_store( be, db, key, idl );
+ }
+ idl_free( tmp );
+ cont_free( &data );
+ idl_free( idl );
+ return 0;
+ }
+ idl_free( tmp );
+ }
+
+ cont_free( &data );
+ idl_free( idl );
+ return -1;
+}
+
+
+/* return a duplicate of a single ID_BLOCK */
+static ID_BLOCK *
+idl_dup( ID_BLOCK *idl )