typedef struct bdb_cache {
int c_maxsize;
int c_cursize;
+ int c_eiused;
+/* c_eiused shows how many EntryInfos are in use. It should
+ * also equal the length of the LRU list, i.e., everything now lives
+ * on the LRU list. c_cursize shows how many Entries are attached.
+ * c_cursize will be <= c_eiused because internal nodes of the DIT
+ * will be retained in memory as long as their children are in use.
+ */
EntryInfo c_dntree;
EntryInfo *c_eifree; /* free list */
Avlnode *c_idtree;
ei->bei_rdn.bv_val = NULL;
#endif
} else {
+ bdb->bi_cache.c_eiused++;
ber_dupbv( &ei2->bei_nrdn, &ei->bei_nrdn );
avl_insert( &ei->bei_parent->bei_kids, ei2, bdb_rdn_cmp,
avl_dup_error );
} else {
ei2 = &bdb->bi_cache.c_dntree;
}
+ bdb->bi_cache.c_eiused++;
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
/* Got the parent, link in and we're done. */
*/
} else {
bdb_cache_delete_internal( &bdb->bi_cache, elru, 0 );
- bdb_cache_delete_cleanup( &bdb->bi_cache, elru->bei_e );
+ bdb_cache_delete_cleanup( &bdb->bi_cache, elru );
/* break the loop, unsafe to muck with more than one */
elprev = NULL;
void
bdb_cache_delete_cleanup(
Cache *cache,
- Entry *e )
+ EntryInfo *ei )
{
- EntryInfo *ei = BEI(e);
-
- ei->bei_e = NULL;
- e->e_private = NULL;
- bdb_entry_return( e );
+ if ( ei->bei_e ) {
+ ei->bei_e->e_private = NULL;
+ bdb_entry_return( ei->bei_e );
+ ei->bei_e = NULL;
+ }
free( ei->bei_nrdn.bv_val );
ei->bei_nrdn.bv_val = NULL;
return rc;
}
+ cache->c_eiused--;
+
/* lru */
LRU_DELETE( cache, e );
- cache->c_cursize--;
+ if ( e->bei_e ) cache->c_cursize--;
/* free cache write lock */
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
if( e != NULL ) {
if ( rs->sr_err == LDAP_SUCCESS ) {
/* Free the EntryInfo and the Entry */
- bdb_cache_delete_cleanup( &bdb->bi_cache, e );
+ bdb_cache_delete_cleanup( &bdb->bi_cache, BEI(e) );
} else {
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
}