X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-ldbm%2Fidl.c;h=7a4f7d075e0c71dc90aa288e8f922660247b8a3a;hb=802325542ba979998c707b57c311129bfddf4ae8;hp=205b5b06488554a8de51c0989632f984b7b43ddf;hpb=97e88afb5ee53bd10ae7ee8008d46360183c4e59;p=openldap diff --git a/servers/slapd/back-ldbm/idl.c b/servers/slapd/back-ldbm/idl.c index 205b5b0648..7a4f7d075e 100644 --- a/servers/slapd/back-ldbm/idl.c +++ b/servers/slapd/back-ldbm/idl.c @@ -1,14 +1,16 @@ /* idl.c - ldap id list handling routines */ +#include "portable.h" + #include -#include -#include -#include "slap.h" + +#include +#include + #include "ldapconfig.h" +#include "slap.h" #include "back-ldbm.h" -extern Datum ldbm_cache_fetch(); - IDList * idl_alloc( int nids ) { @@ -51,11 +53,10 @@ idl_fetch_one( Datum key ) { - Datum data, k2; + Datum data; IDList *idl; - IDList **tmp; - char *kstr; - int i, nids; + + ldbm_datum_init( data ); /* Debug( LDAP_DEBUG_TRACE, "=> idl_fetch_one\n", 0, 0, 0 ); */ @@ -79,6 +80,9 @@ idl_fetch( char *kstr; int i, nids; + ldbm_datum_init( k2 ); + ldbm_datum_init( data ); + /* Debug( LDAP_DEBUG_TRACE, "=> idl_fetch\n", 0, 0, 0 ); */ data = ldbm_cache_fetch( db, key ); @@ -117,7 +121,7 @@ idl_fetch( kstr = (char *) ch_malloc( key.dsize + 20 ); nids = 0; for ( i = 0; idl->b_ids[i] != NOID; i++ ) { - sprintf( kstr, "%c%s%d", CONT_PREFIX, key.dptr, idl->b_ids[i] ); + sprintf( kstr, "%c%s%ld", CONT_PREFIX, key.dptr, idl->b_ids[i] ); k2.dptr = kstr; k2.dsize = strlen( kstr ) + 1; @@ -151,8 +155,8 @@ idl_fetch( } free( (char *) tmp ); - Debug( LDAP_DEBUG_TRACE, "<= idl_fetch %d ids (%d max)\n", idl->b_nids, - idl->b_nmax, 0 ); + Debug( LDAP_DEBUG_TRACE, "<= idl_fetch %lu ids (%lu max)\n", + idl->b_nids, idl->b_nmax, 0 ); return( idl ); } @@ -164,15 +168,25 @@ idl_store( IDList *idl ) { - int rc; + int rc, flags; Datum data; + struct ldbminfo *li = (struct ldbminfo *) be->be_private; + + ldbm_datum_init( data ); /* Debug( LDAP_DEBUG_TRACE, "=> idl_store\n", 0, 0, 0 ); */ data.dptr = (char *) idl; data.dsize = (2 + idl->b_nmax) * sizeof(ID); + +#ifdef LDBM_DEBUG + Statslog( LDAP_DEBUG_STATS, "<= idl_store(): rc=%d\n", + rc, 0, 0, 0, 0 ); +#endif - rc = ldbm_cache_store( db, key, data, LDBM_REPLACE | LDBM_SYNC ); + flags = LDBM_REPLACE; + if( li->li_dbcachewsync ) flags |= LDBM_SYNC; + rc = ldbm_cache_store( db, key, data, flags ); /* Debug( LDAP_DEBUG_TRACE, "<= idl_store %d\n", rc, 0, 0 ); */ return( rc ); @@ -186,7 +200,7 @@ idl_split_block( IDList **n2 ) { - int i; + unsigned int i; /* find where to split the block */ for ( i = 0; i < b->b_nids && id > b->b_ids[i]; i++ ) @@ -246,7 +260,7 @@ idl_change_first( } /* write block with new key */ - sprintf( bkey.dptr, "%c%s%d", CONT_PREFIX, hkey.dptr, b->b_ids[0] ); + sprintf( bkey.dptr, "%c%s%ld", CONT_PREFIX, hkey.dptr, b->b_ids[0] ); bkey.dsize = strlen( bkey.dptr ) + 1; if ( (rc = idl_store( be, db, bkey, b )) != 0 ) { Debug( LDAP_DEBUG_ANY, @@ -278,7 +292,14 @@ idl_insert_key( char *kstr; Datum k2; + ldbm_datum_init( k2 ); + if ( (idl = idl_fetch_one( be, db, key )) == NULL ) { +#ifdef LDBM_DEBUG + Statslog( LDAP_DEBUG_STATS, "=> idl_insert_key(): no key yet\n", + 0, 0, 0, 0, 0 ); +#endif + idl = idl_alloc( 1 ); idl->b_ids[idl->b_nids++] = id; rc = idl_store( be, db, key, idl ); @@ -326,14 +347,14 @@ idl_insert_key( /* store the first id block */ kstr = (char *) ch_malloc( key.dsize + 20 ); - sprintf( kstr, "%c%s%d", CONT_PREFIX, key.dptr, + sprintf( kstr, "%c%s%ld", CONT_PREFIX, key.dptr, tmp->b_ids[0] ); k2.dptr = kstr; k2.dsize = strlen( kstr ) + 1; rc = idl_store( be, db, k2, tmp ); /* store the second id block */ - sprintf( kstr, "%c%s%d", CONT_PREFIX, key.dptr, + sprintf( kstr, "%c%s%ld", CONT_PREFIX, key.dptr, tmp2->b_ids[0] ); k2.dptr = kstr; k2.dsize = strlen( kstr ) + 1; @@ -369,7 +390,7 @@ idl_insert_key( /* get the block */ kstr = (char *) ch_malloc( key.dsize + 20 ); - sprintf( kstr, "%c%s%d", CONT_PREFIX, key.dptr, idl->b_ids[i] ); + sprintf( kstr, "%c%s%ld", CONT_PREFIX, key.dptr, idl->b_ids[i] ); k2.dptr = kstr; k2.dsize = strlen( kstr ) + 1; if ( (tmp = idl_fetch_one( be, db, k2 )) == NULL ) { @@ -411,7 +432,7 @@ idl_insert_key( /* is there a next block? */ if ( !first && idl->b_ids[i + 1] != NOID ) { /* read it in */ - sprintf( kstr, "%c%s%d", CONT_PREFIX, key.dptr, + sprintf( kstr, "%c%s%ld", CONT_PREFIX, key.dptr, idl->b_ids[i + 1] ); k2.dptr = kstr; k2.dsize = strlen( kstr ) + 1; @@ -433,7 +454,7 @@ idl_insert_key( case 0: /* id inserted */ if ( rc == 2 ) { Debug( LDAP_DEBUG_ANY, - "id %d already in next block\n", + "id %lu already in next block\n", id, 0, 0 ); } free( kstr ); @@ -470,7 +491,7 @@ idl_insert_key( /* delete all indirect blocks */ for ( j = 0; idl->b_ids[j] != NOID; j++ ) { - sprintf( kstr, "%c%s%d", CONT_PREFIX, key.dptr, + sprintf( kstr,"%c%s%ld", CONT_PREFIX, key.dptr, idl->b_ids[j] ); k2.dptr = kstr; k2.dsize = strlen( kstr ) + 1; @@ -509,14 +530,14 @@ idl_insert_key( rc = idl_store( be, db, key, tmp ); /* store the first id block */ - sprintf( kstr, "%c%s%d", CONT_PREFIX, key.dptr, + sprintf( kstr, "%c%s%ld", CONT_PREFIX, key.dptr, tmp2->b_ids[0] ); k2.dptr = kstr; k2.dsize = strlen( kstr ) + 1; rc = idl_store( be, db, k2, tmp2 ); /* store the second id block */ - sprintf( kstr, "%c%s%d", CONT_PREFIX, key.dptr, + sprintf( kstr, "%c%s%ld", CONT_PREFIX, key.dptr, tmp3->b_ids[0] ); k2.dptr = kstr; k2.dsize = strlen( kstr ) + 1; @@ -544,7 +565,7 @@ idl_insert_key( int idl_insert( IDList **idl, ID id, int maxids ) { - int i, j; + unsigned int i, j; if ( ALLIDS( *idl ) ) { return( 2 ); /* already there */ @@ -585,6 +606,94 @@ idl_insert( IDList **idl, ID id, int maxids ) return( i == 0 ? 1 : 0 ); /* inserted - first id changed or not */ } +int +idl_delete_key ( + Backend *be, + struct dbcache *db, + Datum key, + ID id +) +{ + Datum k2; + IDList *idl, *tmp; + unsigned i; + int j, nids; + char *kstr; + + if ( (idl = idl_fetch_one( be, db, key ) ) == NULL ) + { + /* It wasn't found. Hmm... */ + return -1; + } + + if ( ! INDIRECT_BLOCK( idl ) ) + { + for ( i=0; i < idl->b_nids; i++ ) + { + if ( idl->b_ids[i] == id ) + { + memcpy ( &idl->b_ids[i], &idl->b_ids[i+1], sizeof(ID)*(idl->b_nids-(i+1))); + idl->b_ids[idl->b_nids-1] = NOID; + idl->b_nids--; + if ( idl->b_nids ) + idl_store( be, db, key, idl ); + else + ldbm_cache_delete( db, key ); + return 0; + } + /* We didn't find the ID. Hmmm... */ + } + return -1; + } + + /* We have to go through an indirect block and find the ID + in the list of IDL's + */ + for ( nids = 0; idl->b_ids[nids] != NOID; nids++ ) + ; /* NULL */ + kstr = (char *) ch_malloc( key.dsize + 20 ); + for ( j = 0; idl->b_ids[j] != NOID; j++ ) + { + ldbm_datum_init( k2 ); + sprintf( kstr, "%c%s%ld", CONT_PREFIX, key.dptr, idl->b_ids[j] ); + k2.dptr = kstr; + k2.dsize = strlen( kstr ) + 1; + + if ( (tmp = idl_fetch_one( be, db, k2 )) == NULL ) { + Debug( LDAP_DEBUG_ANY, + "idl_fetch of (%s) returns NULL\n", k2.dptr, 0, 0 ); + continue; + } + /* + Now try to find the ID in tmp + */ + for ( i=0; i < tmp->b_nids; i++ ) + { + if ( tmp->b_ids[i] == id ) + { + memcpy ( &tmp->b_ids[i], &tmp->b_ids[i+1], sizeof(ID)*(tmp->b_nids-(i+1))); + tmp->b_ids[tmp->b_nids-1] = NOID; + tmp->b_nids--; + if ( tmp->b_nids ) + idl_store ( be, db, k2, tmp ); + else + { + ldbm_cache_delete( db, k2 ); + memcpy ( &idl->b_ids[j], &idl->b_ids[j+1], sizeof(ID)*(nids-(j+1))); + idl->b_ids[nids-1] = NOID; + nids--; + if ( ! nids ) + ldbm_cache_delete( db, key ); + else + idl_store( be, db, key, idl ); + } + return 0; + } + } + } + return -1; +} + static IDList * idl_dup( IDList *idl ) { @@ -618,8 +727,8 @@ idl_intersection( IDList *b ) { - int ai, bi, ni; - IDList *n; + unsigned int ai, bi, ni; + IDList *n; if ( a == NULL || b == NULL ) { return( NULL ); @@ -666,8 +775,8 @@ idl_union( IDList *b ) { - int ai, bi, ni; - IDList *n; + unsigned int ai, bi, ni; + IDList *n; if ( a == NULL ) { return( idl_dup( b ) ); @@ -720,8 +829,8 @@ idl_notin( IDList *b ) { - int ni, ai, bi; - IDList *n; + unsigned int ni, ai, bi; + IDList *n; if ( a == NULL ) { return( NULL ); @@ -799,7 +908,7 @@ idl_firstid( IDList *idl ) ID idl_nextid( IDList *idl, ID id ) { - int i; + unsigned int i; if ( ALLIDS( idl ) ) { return( ++id < idl->b_nids ? id : NOID );