X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-ldbm%2Fidl.c;h=dbcc8f41b7a18eb96df3ff9112b39b427be4a0c5;hb=b0b3eff457f0e431c4fd094d3d9cfeb6383df91d;hp=a070f46adf399002cb42b59d386bad7cc9bb4f01;hpb=6107ba67d2fd7eadb23ffdd1d284306011ef4013;p=openldap diff --git a/servers/slapd/back-ldbm/idl.c b/servers/slapd/back-ldbm/idl.c index a070f46adf..dbcc8f41b7 100644 --- a/servers/slapd/back-ldbm/idl.c +++ b/servers/slapd/back-ldbm/idl.c @@ -1,8 +1,17 @@ /* idl.c - ldap id list handling routines */ /* $OpenLDAP$ */ -/* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2003 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ #include "portable.h" @@ -48,17 +57,29 @@ static void cont_free( Datum *cont ) #ifdef LDBM_DEBUG_IDL static void idl_check(ID_BLOCK *idl) { - int i; + int i, max; ID_BLOCK last; - if( ID_BLOCK_INDIRECT(idl) || ID_BLOCK_ALLIDS(idl) - || ID_BLOCK_NIDS(idl) <= 1 ) + if( ID_BLOCK_ALLIDS(idl) ) + { + return; + } +#ifndef USE_INDIRECT_NIDS + if( ID_BLOCK_INDIRECT(idl) ) + { + for ( max = 0; !ID_BLOCK_NOID(idl, max); max++ ) ; + } else +#endif + { + max = ID_BLOCK_NIDS(idl); + } + if ( max <= 1 ) { return; } for( last = ID_BLOCK_ID(idl, 0), i = 1; - i < ID_BLOCK_NIDS(idl); + i < max; last = ID_BLOCK_ID(idl, i), i++ ) { assert (last < ID_BLOCK_ID(idl, i) ); @@ -170,8 +191,7 @@ idl_fetch( Datum data; ID_BLOCK *idl; ID_BLOCK **tmp; - int nids; - unsigned i; + unsigned i, nids, nblocks; idl = idl_fetch_one( be, db, key ); @@ -197,21 +217,17 @@ idl_fetch( #ifndef USE_INDIRECT_NIDS /* count the number of blocks & allocate space for pointers to them */ - for ( i = 0; !ID_BLOCK_NOID(idl, i); i++ ) + for ( nblocks = 0; !ID_BLOCK_NOID(idl, nblocks); nblocks++ ) ; /* NULL */ #else - i = ID_BLOCK_NIDS(idl); + nblocks = ID_BLOCK_NIDS(idl); #endif - tmp = (ID_BLOCK **) ch_malloc( (i + 1) * sizeof(ID_BLOCK *) ); + tmp = (ID_BLOCK **) ch_malloc( nblocks * sizeof(ID_BLOCK *) ); /* read in all the blocks */ cont_alloc( &data, &key ); nids = 0; -#ifndef USE_INDIRECT_NIDS - for ( i = 0; !ID_BLOCK_NOID(idl, i); i++ ) { -#else - for ( i = 0; i < ID_BLOCK_NIDS(idl); i++ ) { -#endif + for ( i = 0; i < nblocks; i++ ) { cont_id( &data, ID_BLOCK_ID(idl, i) ); if ( (tmp[i] = idl_fetch_one( be, db, data )) == NULL ) { @@ -228,7 +244,6 @@ idl_fetch( nids += ID_BLOCK_NIDS(tmp[i]); } - tmp[i] = NULL; cont_free( &data ); idl_free( idl ); @@ -238,7 +253,7 @@ idl_fetch( nids = 0; /* copy in all the ids from the component blocks */ - for ( i = 0; tmp[i] != NULL; i++ ) { + for ( i = 0; i < nblocks; i++ ) { if ( tmp[i] == NULL ) { continue; } @@ -253,6 +268,8 @@ idl_fetch( } free( (char *) tmp ); + assert( ID_BLOCK_NIDS(idl) == nids ); + #ifdef LDBM_DEBUG_IDL idl_check(idl); #endif @@ -296,11 +313,6 @@ idl_store( flags = LDBM_REPLACE; rc = ldbm_cache_store( db, key, data, flags ); -#ifdef LDBM_DEBUG - Statslog( LDAP_DEBUG_STATS, "<= idl_store(): rc=%d\n", - rc, 0, 0, 0, 0 ); -#endif - /* Debug( LDAP_DEBUG_TRACE, "<= idl_store %d\n", rc, 0, 0 ); */ return( rc ); } @@ -550,14 +562,13 @@ idl_insert_key( #ifndef USE_INDIRECT_NIDS /* select the block to try inserting into *//* XXX linear search XXX */ - for ( i = 0; !ID_BLOCK_NOID(idl, i) && id > ID_BLOCK_ID(idl, i); i++ ) + for ( i = 0; !ID_BLOCK_NOID(idl, i) && id >= ID_BLOCK_ID(idl, i); i++ ) ; /* NULL */ #else i = idl_find(idl, id); - if (ID_BLOCK_ID(idl, i) < id) + if (ID_BLOCK_ID(idl, i) <= id) i++; #endif - if ( i != 0 ) { i--; first = 0; @@ -565,6 +576,11 @@ idl_insert_key( first = 1; } + /* At this point, the following condition must be true: + * ID_BLOCK_ID(idl, i) <= id && id < ID_BLOCK_ID(idl, i+1) + * except when i is the first or the last block. + */ + /* get the block */ cont_alloc( &k2, &key ); cont_id( &k2, ID_BLOCK_ID(idl, i) ); @@ -626,10 +642,11 @@ idl_insert_key( #else if ( !first && (unsigned long)(i + 1) < ID_BLOCK_NIDS(idl) ) { #endif + Datum k3; /* read it in */ - cont_alloc( &k2, &key ); - cont_id( &k2, ID_BLOCK_ID(idl, i) ); - if ( (tmp2 = idl_fetch_one( be, db, k2 )) == NULL ) { + cont_alloc( &k3, &key ); + cont_id( &k3, ID_BLOCK_ID(idl, i + 1) ); + if ( (tmp2 = idl_fetch_one( be, db, k3 )) == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( INDEX, ERR, "idl_insert_key: idl_fetch_one returned NULL\n", 0, 0, 0); @@ -640,7 +657,7 @@ idl_insert_key( #endif /* split the original block */ - cont_free( &k2 ); + cont_free( &k3 ); goto split; } @@ -680,7 +697,7 @@ idl_insert_key( db->dbc_maxids )) ) { case 1: /* id inserted first in block */ rc = idl_change_first( be, db, key, idl, - i + 1, k2, tmp2 ); + i + 1, k3, tmp2 ); /* FALL */ case 2: /* id already there - how? */ @@ -704,6 +721,8 @@ idl_insert_key( idl_free( tmp ); idl_free( tmp2 ); + cont_free( &k3 ); + cont_free( &k2 ); idl_free( idl ); return( 0 ); @@ -712,6 +731,7 @@ idl_insert_key( } idl_free( tmp2 ); + cont_free( &k3 ); } split: