1 /* cache.c - routines to maintain an in-core cache of entries */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2001-2003 The OpenLDAP Foundation.
6 * Portions Copyright 2001-2003 Pierangelo Masarati.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software.
28 #include "back-monitor.h"
31 * compares entries based on the dn
39 struct monitorcache *cc1 = ( struct monitorcache * )c1;
40 struct monitorcache *cc2 = ( struct monitorcache * )c2;
43 * case sensitive, because the dn MUST be normalized
45 return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn );
49 * checks for duplicate entries
57 struct monitorcache *cc1 = ( struct monitorcache * )c1;
58 struct monitorcache *cc2 = ( struct monitorcache * )c2;
61 * case sensitive, because the dn MUST be normalized
63 return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn ) == 0 ? -1 : 0;
67 * adds an entry to the cache and inits the mutex
71 struct monitorinfo *mi,
75 struct monitorcache *mc;
76 struct monitorentrypriv *mp;
82 mp = ( struct monitorentrypriv *)e->e_private;
83 ldap_pvt_thread_mutex_init( &mp->mp_mutex );
85 mc = ( struct monitorcache * )ch_malloc( sizeof( struct monitorcache ) );
86 mc->mc_ndn = e->e_nname;
88 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
89 rc = avl_insert( &mi->mi_cache, ( caddr_t )mc,
90 monitor_cache_cmp, monitor_cache_dup );
91 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
97 * locks the entry (no r/w)
104 struct monitorentrypriv *mp;
107 assert( e->e_private != NULL );
109 mp = ( struct monitorentrypriv * )e->e_private;
110 ldap_pvt_thread_mutex_lock( &mp->mp_mutex );
116 * gets an entry from the cache based on the normalized dn
121 struct monitorinfo *mi,
126 struct monitorcache tmp_mc, *mc;
128 assert( mi != NULL );
129 assert( ndn != NULL );
130 assert( ep != NULL );
132 tmp_mc.mc_ndn = *ndn;
133 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
134 mc = ( struct monitorcache * )avl_find( mi->mi_cache,
135 ( caddr_t )&tmp_mc, monitor_cache_cmp );
138 /* entry is returned with mutex locked */
139 monitor_cache_lock( mc->mc_e );
140 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
146 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
153 * If the entry exists in cache, it is returned in locked status;
154 * otherwise, if the parent exists, if it may generate volatile
155 * descendants an attempt to generate the required entry is
156 * performed and, if successful, the entry is returned
159 monitor_cache_dn2entry(
166 struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
168 struct berval p_ndn = { 0L, NULL };
170 struct monitorentrypriv *mp;
172 assert( mi != NULL );
173 assert( ndn != NULL );
174 assert( ep != NULL );
175 assert( matched != NULL );
179 rc = monitor_cache_get( mi, ndn, ep );
180 if ( !rc && *ep != NULL ) {
184 /* try with parent/ancestors */
186 dnParent( ndn, &p_ndn );
189 if ( p_ndn.bv_val == NULL ) {
194 p_ndn.bv_len = ndn->bv_len
195 - ( ber_len_t ) ( p_ndn.bv_val - ndn->bv_val );
198 rc = monitor_cache_dn2entry( op, &p_ndn, &e_parent, matched );
199 if ( rc || e_parent == NULL) {
203 mp = ( struct monitorentrypriv * )e_parent->e_private;
205 if ( mp->mp_flags & MONITOR_F_VOLATILE_CH ) {
206 /* parent entry generates volatile children */
207 rc = monitor_entry_create( op, ndn, e_parent, ep );
211 monitor_cache_release( mi, e_parent );
220 * releases the lock of the entry; if it is marked as volatile, it is
224 monitor_cache_release(
225 struct monitorinfo *mi,
229 struct monitorentrypriv *mp;
231 assert( mi != NULL );
233 assert( e->e_private != NULL );
235 mp = ( struct monitorentrypriv * )e->e_private;
237 if ( mp->mp_flags & MONITOR_F_VOLATILE ) {
238 struct monitorcache *mc, tmp_mc;
240 /* volatile entries do not return to cache */
241 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
242 tmp_mc.mc_ndn = e->e_nname;
243 mc = avl_delete( &mi->mi_cache,
244 ( caddr_t )&tmp_mc, monitor_cache_cmp );
245 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
248 ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );
249 ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
257 ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );