From 5fb7ea22948b3c310a569487fb6b94274a0094cd Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 22 Sep 2003 10:11:10 +0000 Subject: [PATCH] Cleanup prev commit --- servers/slapd/back-bdb/cache.c | 16 +++++++-- servers/slapd/back-bdb/dn2id.c | 52 +++++++++++++++++++----------- servers/slapd/back-bdb/proto-bdb.h | 8 +++++ 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index db5af5fed5..02db20c8c5 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -430,7 +430,10 @@ hdb_cache_find_parent( return rc; } -int hdb_entryinfo_load( +/* Used by hdb_dn2idl when loading the EntryInfo for all the children + * of a given node + */ +int hdb_cache_load( struct bdb_info *bdb, EntryInfo *ei, EntryInfo **res ) @@ -438,16 +441,25 @@ int hdb_entryinfo_load( EntryInfo *ei2; int rc; + /* See if we already have this one */ bdb_cache_entryinfo_lock( ei->bei_parent ); ei2 = (EntryInfo *)avl_find( ei->bei_parent->bei_kids, ei, bdb_rdn_cmp ); bdb_cache_entryinfo_unlock( ei->bei_parent ); + if ( !ei2 ) { + /* Not found, add it */ + struct berval bv; + + /* bei_rdn was not malloc'd before, do it now */ + ber_dupbv( &bv, &ei->bei_rdn ); + ei->bei_rdn = bv; + rc = bdb_entryinfo_add_internal( bdb, ei, res ); bdb_cache_entryinfo_unlock( ei->bei_parent ); ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock ); } else { + /* Found, return it */ *res = ei2; - free( ei->bei_rdn.bv_val ); return 0; } return rc; diff --git a/servers/slapd/back-bdb/dn2id.c b/servers/slapd/back-bdb/dn2id.c index 8dd54061a2..c3cef02e80 100644 --- a/servers/slapd/back-bdb/dn2id.c +++ b/servers/slapd/back-bdb/dn2id.c @@ -767,23 +767,6 @@ hdb_dn2id( return rc; } -static void -hdb_dn2ei( - char *buf, - int len, - EntryInfo *ei ) -{ - diskNode *d = (diskNode *)buf; - char *ptr; - - AC_MEMCPY( &ei->bei_id, &d->entryID, sizeof(ID) ); - AC_MEMCPY( &ei->bei_nrdn.bv_len, &d->nrdnlen, sizeof(d->nrdnlen) ); - ber_str2bv( d->nrdn, ei->bei_nrdn.bv_len, 0, &ei->bei_nrdn ); - ei->bei_rdn.bv_len = len - sizeof(diskNode) - ei->bei_nrdn.bv_len; - ptr = d->nrdn + ei->bei_nrdn.bv_len + 1; - ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn ); -} - int hdb_dn2id_parent( Operation *op, @@ -916,6 +899,9 @@ struct dn2id_cookie { Operation *op; }; +/* Stuff for iterating over a bei_kids AVL tree and adding the + * IDs to an IDL + */ struct apply_arg { ID *idl; EntryInfo **ei; @@ -955,6 +941,9 @@ hdb_dn2idl_internal( #endif BDB_IDL_ZERO( cx->tmp ); + /* If number of kids in the cache differs from on-disk, load + * up all the kids from the database + */ if ( cx->ei->bei_ckids+1 != cx->ei->bei_dkids ) { EntryInfo ei; ei.bei_parent = cx->ei; @@ -973,12 +962,18 @@ hdb_dn2idl_internal( if ( cx->rc == DB_NOTFOUND ) goto saveit; if ( cx->rc ) return cx->rc; + /* If the on-disk count is zero we've never checked it. + * Count it now. + */ if ( !cx->ei->bei_dkids ) { db_recno_t dkids; cx->dbc->c_count( cx->dbc, &dkids, 0 ); cx->ei->bei_dkids = dkids; } + /* If there are kids and this is a subtree search, allocate + * temp storage for the list of kids. + */ if ( cx->prefix == DN_SUBTREE_PREFIX && cx->ei->bei_dkids > 1 ) { eilist = cx->op->o_tmpalloc( sizeof(EntryInfo *) * cx->ei->bei_dkids, cx->op->o_tmpmemctx ); eilist[cx->ei->bei_dkids-1] = NULL; @@ -999,9 +994,18 @@ hdb_dn2idl_internal( DB_MULTIPLE_NEXT( cx->ptr, &cx->data, j, len ); if (j) { EntryInfo *ei2; - hdb_dn2ei( j, len, &ei ); + diskNode *d = (diskNode *)j; + + AC_MEMCPY( &ei.bei_id, &d->entryID, sizeof(ID) ); + AC_MEMCPY( &ei.bei_nrdn.bv_len, &d->nrdnlen, sizeof(d->nrdnlen) ); + /* nrdn/rdn are set in-place. + * hdb_cache_load will copy them as needed + */ + ei.bei_nrdn.bv_val = d->nrdn; + ei.bei_rdn.bv_len = len - sizeof(diskNode) - ei.bei_nrdn.bv_len; + ei.bei_rdn.bv_val = d->nrdn + ei.bei_nrdn.bv_len + 1; bdb_idl_insert( cx->tmp, ei.bei_id ); - hdb_entryinfo_load( cx->bdb, &ei, &ei2 ); + hdb_cache_load( cx->bdb, &ei, &ei2 ); if ( eilist ) *ptr++ = ei2; } @@ -1009,12 +1013,21 @@ hdb_dn2idl_internal( } cx->dbc->c_close( cx->dbc ); } else { + /* The in-memory cache is in sync with the on-disk data. + * do we have any kids? + */ if ( cx->ei->bei_ckids > 0 ) { struct apply_arg ap; + + /* Temp storage for subtree search */ if ( cx->prefix == DN_SUBTREE_PREFIX ) { eilist = cx->op->o_tmpalloc( sizeof(EntryInfo *) * cx->ei->bei_dkids, cx->op->o_tmpmemctx ); eilist[cx->ei->bei_dkids-1] = NULL; } + + /* Walk the kids tree; order is irrelevant since bdb_idl_insert + * will insert in sorted order. + */ ap.idl = cx->tmp; ap.ei = eilist; bdb_cache_entryinfo_lock( cx->ei ); @@ -1044,6 +1057,7 @@ gotit: cx->ei = *ptr; cx->id = cx->ei->bei_id; hdb_dn2idl_internal( cx ); + } cx->op->o_tmpfree( eilist, cx->op->o_tmpmemctx ); cx->rc = 0; } else { diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index 9a9bd3bd4e..c791c028c9 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -480,6 +480,14 @@ void bdb_cache_delete_cleanup( ); void bdb_cache_release_all( Cache *cache ); +#ifdef BDB_HIER +int hdb_cache_load( + struct bdb_info *bdb, + EntryInfo *ei, + EntryInfo **res +); +#endif + #define bdb_cache_entry_db_relock BDB_SYMBOL(cache_entry_db_relock) int bdb_cache_entry_db_relock( DB_ENV *env,