From: Howard Chu Date: Wed, 23 Apr 2003 08:46:23 +0000 (+0000) Subject: Subtree rename support for the cache X-Git-Tag: OPENLDAP_REL_ENG_2_2_0ALPHA~269 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=02217c91839f654171cad968c4fd0fe3bec2307f;p=openldap Subtree rename support for the cache --- diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h index 8c85099979..bd789d43cb 100644 --- a/servers/slapd/back-bdb/back-bdb.h +++ b/servers/slapd/back-bdb/back-bdb.h @@ -92,6 +92,7 @@ typedef struct bdb_entry_info { struct berval bei_nrdn; #ifdef BDB_HIER struct berval bei_rdn; + int bei_modrdns; #endif Entry *bei_e; Avlnode *bei_kids; diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index 069dcaec5a..b4d0c9f231 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -260,6 +260,9 @@ bdb_entryinfo_add_internal( elru->bei_lrunext = NULL; elru->bei_lruprev = NULL; elru->bei_state = 0; +#ifdef BDB_HIER + elru->bei_modrdns = 0; +#endif ei2 = elru; } if (cache->c_cursize < cache->c_maxsize) @@ -561,15 +564,29 @@ bdb_cache_find_id( *eip, 1, 0, lock ); ep->e_private = *eip; #ifdef BDB_HIER - bdb_fix_dn( ep ); + bdb_fix_dn( ep, 0 ); #endif (*eip)->bei_e = ep; bdb_cache_entry_db_relock( bdb->bi_dbenv, locker, *eip, 0, 0, lock ); } } else { +#ifdef BDB_HIER + rc = bdb_fix_dn( (*eip)->bei_e, 1 ); + if ( rc ) { + bdb_cache_entry_db_lock( bdb->bi_dbenv, + locker, *eip, 1, 0, lock ); + rc = bdb_fix_dn( (*eip)->bei_e, 2 ); + bdb_cache_entry_db_relock( bdb->bi_dbenv, + locker, *eip, 0, 0, lock ); + } else { + bdb_cache_entry_db_lock( bdb->bi_dbenv, + locker, *eip, 0, 0, lock ); + } +#else bdb_cache_entry_db_lock( bdb->bi_dbenv, locker, *eip, 0, 0, lock ); +#endif } } if ( rc == 0 && (*eip)->bei_kids == NULL ) { @@ -731,6 +748,16 @@ bdb_cache_modrdn( bdb_cache_entryinfo_unlock( pei ); bdb_cache_entryinfo_lock( ein ); } +#ifdef BDB_HIER + { int max = ei->bei_modrdns; + /* Record the generation number of this change */ + for ( pei = ein; pei->bei_parent; pei = pei->bei_parent ) { + if ( pei->bei_modrdns > max ) + max = pei->bei_modrdns; + } + ei->bei_modrdns = max + 1; + } +#endif avl_insert( &ein->bei_kids, ei, bdb_rdn_cmp, avl_dup_error ); bdb_cache_entryinfo_unlock( ein ); return rc; diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c index fa0c7e601f..eed36ae231 100644 --- a/servers/slapd/back-bdb/dn2id.c +++ b/servers/slapd/back-bdb/dn2id.c @@ -545,17 +545,34 @@ bdb_dup_compare( /* This function constructs a full DN for a given entry. */ int bdb_fix_dn( - Entry *e + Entry *e, + int checkit ) { EntryInfo *ei; int rlen = 0, nrlen = 0; char *ptr, *nptr; + int max = 0; for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) { rlen += ei->bei_rdn.bv_len + 1; nrlen += ei->bei_nrdn.bv_len + 1; + if (ei->bei_modrdns > max) max = ei->bei_modrdns; } + + /* See if the entry DN was invalidated by a subtree rename */ + if ( checkit ) { + if ( BEI(e)->bei_modrdns >= max ) { + return 0; + } + /* We found a mismatch, tell the caller to lock it */ + if ( checkit == 1 ) { + return 1; + } + /* checkit == 2. do the fix. */ + free( e->e_name.bv_val ); + } + e->e_name.bv_len = rlen - 1; e->e_nname.bv_len = nrlen - 1; e->e_name.bv_val = ch_malloc(rlen + nrlen); @@ -570,6 +587,7 @@ int bdb_fix_dn( *nptr++ = ','; } } + BEI(e)->bei_modrdns = max; ptr[-1] = '\0'; nptr[-1] = '\0'; diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index 5ea2d12b69..2c3d16a534 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -114,7 +114,7 @@ int bdb_dup_compare( const DBT *usrkey, const DBT *curkey ); -int bdb_fix_dn( Entry *e ); +int bdb_fix_dn( Entry *e, int checkit ); #endif