DB_LOCK lock, *lockp;
EntryInfo *elru, *elnext = NULL;
int count, islocked, eimax;
- int efree = 0, eifree = 0, eicount;
+ int efree = 0, eifree = 0, eicount, ecount;
+#ifdef LDAP_DEBUG
+ int iter;
+#endif
/* Wait for the mutex; we're the only one trying to purge. */
ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_lru_mutex );
if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize )
efree = bdb->bi_cache.c_minfree;
- if ( bdb->bi_cache.c_leaves > eimax )
+ if ( bdb->bi_cache.c_leaves > eimax ) {
eifree = bdb->bi_cache.c_minfree * 10;
+ if ( eifree >= eimax )
+ eifree = eimax / 2;
+ }
if ( !efree && !eifree ) {
ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
count = 0;
eicount = 0;
+ ecount = 0;
+#ifdef LDAP_DEBUG
+ iter = 0;
+#endif
/* Look for an unused entry to remove */
for ( elru = bdb->bi_cache.c_lruhead; elru; elru = elnext ) {
/* Free entry for this node if it's present */
if ( elru->bei_e ) {
+ ecount++;
+
+ /* the cache may have gone over the limit while we
+ * weren't looking, so double check.
+ */
+ if ( !efree && ecount > bdb->bi_cache.c_maxsize )
+ efree = bdb->bi_cache.c_minfree;
+
if ( count < efree ) {
elru->bei_e->e_private = NULL;
#ifdef SLAP_ZONE_ALLOC
bdb_cache_entryinfo_unlock( elru );
if ( count >= efree && eicount >= eifree ) {
- if ( count ) {
+ if ( count || ecount > bdb->bi_cache.c_cursize ) {
ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
+ /* HACK: we seem to be losing track, fix up now */
+ if ( ecount > bdb->bi_cache.c_cursize )
+ bdb->bi_cache.c_cursize = ecount;
bdb->bi_cache.c_cursize -= count;
ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
}
bottom:
if ( elnext == bdb->bi_cache.c_lruhead )
break;
+#ifdef LDAP_DEBUG
+ iter++;
+#endif
}
bdb->bi_cache.c_lruhead = elnext;
{
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
Entry *ep = NULL;
- int rc = 0, load = 0, added = 0;
+ int rc = 0, load = 0;
EntryInfo ei = { 0 };
ei.bei_id = id;
*/
if ( (*eip)->bei_state & CACHE_ENTRY_NOT_CACHED ) {
(*eip)->bei_state &= ~CACHE_ENTRY_NOT_CACHED;
- added = 1;
}
flag &= ~ID_NOCACHE;
}
#endif
ep = NULL;
bdb_cache_lru_link( bdb, *eip );
- added = 1;
if (( flag & ID_NOCACHE ) &&
( bdb_cache_entryinfo_trylock( *eip ) == 0 )) {
/* Set the cached state only if no other thread
if ( rc == 0 ) {
int purge = 0;
- if ( added ) {
+ if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ||
+ bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) {
ldap_pvt_thread_mutex_lock( &bdb->bi_cache.c_count_mutex );
- if ( !( flag & ID_NOCACHE )) {
- bdb->bi_cache.c_cursize++;
- if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize &&
- !bdb->bi_cache.c_purging ) {
+ if ( !bdb->bi_cache.c_purging ) {
+ if ( !( flag & ID_NOCACHE )) {
+ bdb->bi_cache.c_cursize++;
+ if ( bdb->bi_cache.c_cursize > bdb->bi_cache.c_maxsize ) {
+ purge = 1;
+ bdb->bi_cache.c_purging = 1;
+ }
+ } else if ( bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax ) {
purge = 1;
bdb->bi_cache.c_purging = 1;
}
- } else if ( bdb->bi_cache.c_leaves > bdb->bi_cache.c_eimax && !bdb->bi_cache.c_purging ) {
- purge = 1;
- bdb->bi_cache.c_purging = 1;
}
ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_count_mutex );
}
/* DB_ENV *env = key; */
DB_TXN *txn = data;
- TXN_ABORT( txn );
+ if ( txn ) TXN_ABORT( txn );
}
/* free up any keys used by the main thread */