]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/cache.c
Cleanup result handling
[openldap] / servers / slapd / back-monitor / cache.c
1 /* cache.c - routines to maintain an in-core cache of entries */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2001-2004 The OpenLDAP Foundation.
6  * Portions Copyright 2001-2003 Pierangelo Masarati.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
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>.
16  */
17 /* ACKNOWLEDGEMENTS:
18  * This work was initially developed by Pierangelo Masarati for inclusion
19  * in OpenLDAP Software.
20  */
21
22 #include "portable.h"
23
24 #include <stdio.h>
25
26 #include "slap.h"
27
28 #include "back-monitor.h"
29
30 /*
31  * compares entries based on the dn
32  */
33 int
34 monitor_cache_cmp(
35                 const void *c1,
36                 const void *c2
37 )
38 {
39         struct monitorcache     *cc1 = ( struct monitorcache * )c1;
40         struct monitorcache     *cc2 = ( struct monitorcache * )c2;
41
42         /*
43          * case sensitive, because the dn MUST be normalized
44          */
45         return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn );
46 }
47
48 /*
49  * checks for duplicate entries
50  */
51 int
52 monitor_cache_dup(
53                 void *c1,
54                 void *c2
55 )
56 {
57         struct monitorcache *cc1 = ( struct monitorcache * )c1;
58         struct monitorcache *cc2 = ( struct monitorcache * )c2;
59
60         /*
61          * case sensitive, because the dn MUST be normalized
62          */
63         return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn ) == 0 ? -1 : 0;
64 }
65
66 /*
67  * adds an entry to the cache and inits the mutex
68  */
69 int
70 monitor_cache_add(
71                 struct monitorinfo      *mi,
72                 Entry                   *e
73 )
74 {
75         struct monitorcache     *mc;
76         struct monitorentrypriv *mp;
77         int                     rc;
78
79         assert( mi != NULL );
80         assert( e != NULL );
81
82         mp = ( struct monitorentrypriv *)e->e_private;
83         ldap_pvt_thread_mutex_init( &mp->mp_mutex );
84
85         mc = ( struct monitorcache * )ch_malloc( sizeof( struct monitorcache ) );
86         mc->mc_ndn = e->e_nname;
87         mc->mc_e = e;
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 );
92
93         return rc;
94 }
95
96 /*
97  * locks the entry (no r/w)
98  */
99 int
100 monitor_cache_lock(
101                 Entry                   *e
102 )
103 {
104                 struct monitorentrypriv *mp;
105
106                 assert( e != NULL );
107                 assert( e->e_private != NULL );
108
109                 mp = ( struct monitorentrypriv * )e->e_private;
110                 ldap_pvt_thread_mutex_lock( &mp->mp_mutex );
111
112                 return( 0 );
113 }
114
115 /*
116  * gets an entry from the cache based on the normalized dn 
117  * with mutex locked
118  */
119 int
120 monitor_cache_get(
121                 struct monitorinfo      *mi,
122                 struct berval           *ndn,
123                 Entry                   **ep
124 )
125 {
126         struct monitorcache tmp_mc, *mc;
127
128         assert( mi != NULL );
129         assert( ndn != NULL );
130         assert( ep != NULL );
131
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 );
136
137         if ( mc != NULL ) {
138                 /* entry is returned with mutex locked */
139                 monitor_cache_lock( mc->mc_e );
140                 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
141                 *ep = mc->mc_e;
142
143                 return( 0 );
144         }
145         
146         ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
147         *ep = NULL;
148
149         return( -1 );
150 }
151
152 /*
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
157  */
158 int
159 monitor_cache_dn2entry(
160                 Operation               *op,
161                 struct berval           *ndn,
162                 Entry                   **ep,
163                 Entry                   **matched
164 )
165 {
166         struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
167         int                     rc;
168         struct berval           p_ndn = { 0L, NULL };
169         Entry                   *e_parent;
170         struct monitorentrypriv *mp;
171                 
172         assert( mi != NULL );
173         assert( ndn != NULL );
174         assert( ep != NULL );
175         assert( matched != NULL );
176
177         *matched = NULL;
178
179         rc = monitor_cache_get( mi, ndn, ep );
180         if ( !rc && *ep != NULL ) {
181                 return( 0 );
182         }
183
184         /* try with parent/ancestors */
185         if ( ndn->bv_len ) {
186                 dnParent( ndn, &p_ndn );
187         }
188
189         if ( p_ndn.bv_val == NULL ) {
190                 p_ndn.bv_val = "";
191                 p_ndn.bv_len = 0;
192                 
193         } else {
194                 p_ndn.bv_len = ndn->bv_len 
195                         - ( ber_len_t ) ( p_ndn.bv_val - ndn->bv_val );
196         }
197
198         rc = monitor_cache_dn2entry( op, &p_ndn, &e_parent, matched );
199         if ( rc || e_parent == NULL) {
200                 return( -1 );
201         }
202
203         mp = ( struct monitorentrypriv * )e_parent->e_private;
204         rc = -1;
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 );
208         }
209
210         if ( !rc ) {
211                 monitor_cache_release( mi, e_parent );
212         } else {
213                 *matched = e_parent;
214         }
215         
216         return( rc );
217 }
218
219 /*
220  * releases the lock of the entry; if it is marked as volatile, it is
221  * destroyed.
222  */
223 int
224 monitor_cache_release(
225         struct monitorinfo      *mi,
226         Entry                   *e
227 )
228 {
229         struct monitorentrypriv *mp;
230
231         assert( mi != NULL );
232         assert( e != NULL );
233         assert( e->e_private != NULL );
234         
235         mp = ( struct monitorentrypriv * )e->e_private;
236
237         if ( mp->mp_flags & MONITOR_F_VOLATILE ) {
238                 struct monitorcache     *mc, tmp_mc;
239
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 );
246                 ch_free( mc );
247                 
248                 ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );
249                 ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
250                 ch_free( mp );
251                 e->e_private = NULL;
252                 entry_free( e );
253
254                 return( 0 );
255         }
256         
257         ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );
258
259         return( 0 );
260 }
261