1 /* cache.c - routines to maintain an in-core cache of entries */
3 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
7 * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
9 * This work has beed deveolped for the OpenLDAP Foundation
10 * in the hope that it may be useful to the Open Source community,
11 * but WITHOUT ANY WARRANTY.
13 * Permission is granted to anyone to use this software for any purpose
14 * on any computer system, and to alter it and redistribute it, subject
15 * to the following restrictions:
17 * 1. The author and SysNet s.n.c. are not responsible for the consequences
18 * of use of this software, no matter how awful, even if they arise from
21 * 2. The origin of this software must not be misrepresented, either by
22 * explicit claim or by omission. Since few users ever read sources,
23 * credits should appear in the documentation.
25 * 3. Altered versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software. Since few users
27 * ever read sources, credits should appear in the documentation.
28 * SysNet s.n.c. cannot be responsible for the consequences of the
31 * 4. This notice may not be removed or altered.
40 #include "back-monitor.h"
43 * compares entries based on the dn
51 struct monitorcache *cc1 = ( struct monitorcache * )c1;
52 struct monitorcache *cc2 = ( struct monitorcache * )c2;
54 int d = cc1->mc_ndn->bv_len - cc2->mc_ndn->bv_len;
57 * case sensitive, because the dn MUST be normalized
59 return d != 0 ? d : strcmp( cc1->mc_ndn->bv_val, cc2->mc_ndn->bv_val );
63 * checks for duplicate entries
71 struct monitorcache *cc1 = ( struct monitorcache * )c1;
72 struct monitorcache *cc2 = ( struct monitorcache * )c2;
76 * case sensitive, because the dn MUST be normalized
79 int cmp = monitor_cache_cmp( c1, c2 );
81 int d = cc1->mc_ndn->bv_len - cc2->mc_ndn->bv_len;
83 d != 0 ? d : strcmp( cc1->mc_ndn->bv_val, cc2->mc_ndn->bv_val );
86 return cmp == 0 ? -1 : 0;
90 * adds an entry to the cache and inits the mutex
94 struct monitorinfo *mi,
98 struct monitorcache *mc;
99 struct monitorentrypriv *mp;
102 assert( mi != NULL );
105 mp = ( struct monitorentrypriv *)e->e_private;
106 ldap_pvt_thread_mutex_init( &mp->mp_mutex );
108 mc = ( struct monitorcache * )ch_malloc( sizeof( struct monitorcache ) );
109 mc->mc_ndn = &e->e_nname;
111 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
112 rc = avl_insert( &mi->mi_cache, ( caddr_t )mc,
113 monitor_cache_cmp, monitor_cache_dup );
114 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
120 * locks the entry (no r/w)
127 struct monitorentrypriv *mp;
130 assert( e->e_private != NULL );
132 mp = ( struct monitorentrypriv * )e->e_private;
133 ldap_pvt_thread_mutex_lock( &mp->mp_mutex );
139 * gets an entry from the cache based on the normalized dn
144 struct monitorinfo *mi,
149 struct monitorcache tmp_mc, *mc;
151 assert( mi != NULL );
152 assert( ndn != NULL );
153 assert( ep != NULL );
156 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
157 mc = ( struct monitorcache * )avl_find( mi->mi_cache,
158 ( caddr_t )&tmp_mc, monitor_cache_cmp );
161 /* entry is returned with mutex locked */
162 monitor_cache_lock( mc->mc_e );
163 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
169 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
176 * If the entry exists in cache, it is returned in locked status;
177 * otherwise, if the parent exists, if it may generate volatile
178 * descendants an attempt to generate the required entry is
179 * performed and, if successful, the entry is returned
182 monitor_cache_dn2entry(
183 struct monitorinfo *mi,
191 struct berval p_ndn = { 0L, NULL };
193 struct monitorentrypriv *mp;
195 assert( mi != NULL );
196 assert( ndn != NULL );
197 assert( ep != NULL );
198 assert( matched != NULL );
202 rc = monitor_cache_get( mi, ndn, ep );
203 if ( !rc && *ep != NULL ) {
207 /* try with parent/ancestors */
209 dnParent( ndn, &p_ndn );
212 if ( p_ndn.bv_val == NULL ) {
217 p_ndn.bv_len = ndn->bv_len
218 - ( ber_len_t ) ( p_ndn.bv_val - ndn->bv_val );
221 rc = monitor_cache_dn2entry( mi, &p_ndn, &e_parent, matched );
222 if ( rc || e_parent == NULL) {
226 mp = ( struct monitorentrypriv * )e_parent->e_private;
228 if ( mp->mp_flags & MONITOR_F_VOLATILE_CH ) {
229 /* parent entry generates volatile children */
230 rc = monitor_entry_create( mi, ndn, e_parent, ep );
234 monitor_cache_release( mi, e_parent );
243 * releases the lock of the entry; if it is marked as volatile, it is
247 monitor_cache_release(
248 struct monitorinfo *mi,
252 struct monitorentrypriv *mp;
254 assert( mi != NULL );
256 assert( e->e_private != NULL );
258 mp = ( struct monitorentrypriv * )e->e_private;
260 if ( mp->mp_flags & MONITOR_F_VOLATILE ) {
261 struct monitorcache *mc, tmp_mc;
263 /* volatile entries do not return to cache */
264 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
265 tmp_mc.mc_ndn = &e->e_nname;
266 mc = avl_delete( &mi->mi_cache,
267 ( caddr_t )&tmp_mc, monitor_cache_cmp );
268 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
271 ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
279 ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );