]> git.sur5r.net Git - openldap/blob - servers/slapd/back-monitor/cache.c
need attrs when sending entries ...
[openldap] / servers / slapd / back-monitor / cache.c
1 /* cache.c - routines to maintain an in-core cache of entries */
2 /*
3  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /*
7  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
8  * 
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.
12  * 
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:
16  * 
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
19  *    flaws in it.
20  * 
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.
24  * 
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
29  *    alterations.
30  * 
31  * 4. This notice may not be removed or altered.
32  */
33
34 #include "portable.h"
35
36 #include <stdio.h>
37
38 #include "slap.h"
39
40 #include "back-monitor.h"
41
42 /*
43  * compares entries based on the dn
44  */
45 int
46 monitor_cache_cmp(
47                 const void *c1,
48                 const void *c2
49 )
50 {
51         struct monitorcache     *cc1 = ( struct monitorcache * )c1;
52         struct monitorcache     *cc2 = ( struct monitorcache * )c2;
53
54         /*
55          * case sensitive, because the dn MUST be normalized
56          */
57         return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn );
58 }
59
60 /*
61  * checks for duplicate entries
62  */
63 int
64 monitor_cache_dup(
65                 void *c1,
66                 void *c2
67 )
68 {
69         struct monitorcache *cc1 = ( struct monitorcache * )c1;
70         struct monitorcache *cc2 = ( struct monitorcache * )c2;
71
72         /*
73          * case sensitive, because the dn MUST be normalized
74          */
75         return ber_bvcmp( &cc1->mc_ndn, &cc2->mc_ndn ) == 0 ? -1 : 0;
76 }
77
78 /*
79  * adds an entry to the cache and inits the mutex
80  */
81 int
82 monitor_cache_add(
83                 struct monitorinfo      *mi,
84                 Entry                   *e
85 )
86 {
87         struct monitorcache     *mc;
88         struct monitorentrypriv *mp;
89         int                     rc;
90
91         assert( mi != NULL );
92         assert( e != NULL );
93
94         mp = ( struct monitorentrypriv *)e->e_private;
95         ldap_pvt_thread_mutex_init( &mp->mp_mutex );
96
97         mc = ( struct monitorcache * )ch_malloc( sizeof( struct monitorcache ) );
98         mc->mc_ndn = e->e_nname;
99         mc->mc_e = e;
100         ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
101         rc = avl_insert( &mi->mi_cache, ( caddr_t )mc,
102                         monitor_cache_cmp, monitor_cache_dup );
103         ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
104
105         return rc;
106 }
107
108 /*
109  * locks the entry (no r/w)
110  */
111 int
112 monitor_cache_lock(
113                 Entry                   *e
114 )
115 {
116                 struct monitorentrypriv *mp;
117
118                 assert( e != NULL );
119                 assert( e->e_private != NULL );
120
121                 mp = ( struct monitorentrypriv * )e->e_private;
122                 ldap_pvt_thread_mutex_lock( &mp->mp_mutex );
123
124                 return( 0 );
125 }
126
127 /*
128  * gets an entry from the cache based on the normalized dn 
129  * with mutex locked
130  */
131 int
132 monitor_cache_get(
133                 struct monitorinfo      *mi,
134                 struct berval           *ndn,
135                 Entry                   **ep
136 )
137 {
138         struct monitorcache tmp_mc, *mc;
139
140         assert( mi != NULL );
141         assert( ndn != NULL );
142         assert( ep != NULL );
143
144         tmp_mc.mc_ndn = *ndn;
145         ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
146         mc = ( struct monitorcache * )avl_find( mi->mi_cache,
147                         ( caddr_t )&tmp_mc, monitor_cache_cmp );
148
149         if ( mc != NULL ) {
150                 /* entry is returned with mutex locked */
151                 monitor_cache_lock( mc->mc_e );
152                 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
153                 *ep = mc->mc_e;
154
155                 return( 0 );
156         }
157         
158         ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
159         *ep = NULL;
160
161         return( -1 );
162 }
163
164 /*
165  * If the entry exists in cache, it is returned in locked status;
166  * otherwise, if the parent exists, if it may generate volatile 
167  * descendants an attempt to generate the required entry is
168  * performed and, if successful, the entry is returned
169  */
170 int
171 monitor_cache_dn2entry(
172                 struct monitorinfo      *mi,
173                 struct berval           *ndn,
174                 Entry                   **ep,
175                 Entry                   **matched
176 )
177 {
178         int             rc;
179
180         struct berval           p_ndn = { 0L, NULL };
181         Entry                   *e_parent;
182         struct monitorentrypriv *mp;
183                 
184         assert( mi != NULL );
185         assert( ndn != NULL );
186         assert( ep != NULL );
187         assert( matched != NULL );
188
189         *matched = NULL;
190
191         rc = monitor_cache_get( mi, ndn, ep );
192         if ( !rc && *ep != NULL ) {
193                 return( 0 );
194         }
195
196         /* try with parent/ancestors */
197         if ( ndn->bv_len ) {
198                 dnParent( ndn, &p_ndn );
199         }
200
201         if ( p_ndn.bv_val == NULL ) {
202                 p_ndn.bv_val = "";
203                 p_ndn.bv_len = 0;
204                 
205         } else {
206                 p_ndn.bv_len = ndn->bv_len 
207                         - ( ber_len_t ) ( p_ndn.bv_val - ndn->bv_val );
208         }
209
210         rc = monitor_cache_dn2entry( mi, &p_ndn, &e_parent, matched );
211         if ( rc || e_parent == NULL) {
212                 return( -1 );
213         }
214
215         mp = ( struct monitorentrypriv * )e_parent->e_private;
216         rc = -1;
217         if ( mp->mp_flags & MONITOR_F_VOLATILE_CH ) {
218                 /* parent entry generates volatile children */
219                 rc = monitor_entry_create( mi, ndn, e_parent, ep );
220         }
221
222         if ( !rc ) {
223                 monitor_cache_release( mi, e_parent );
224         } else {
225                 *matched = e_parent;
226         }
227         
228         return( rc );
229 }
230
231 /*
232  * releases the lock of the entry; if it is marked as volatile, it is
233  * destroyed.
234  */
235 int
236 monitor_cache_release(
237         struct monitorinfo      *mi,
238         Entry                   *e
239 )
240 {
241         struct monitorentrypriv *mp;
242
243         assert( mi != NULL );
244         assert( e != NULL );
245         assert( e->e_private != NULL );
246         
247         mp = ( struct monitorentrypriv * )e->e_private;
248
249         if ( mp->mp_flags & MONITOR_F_VOLATILE ) {
250                 struct monitorcache     *mc, tmp_mc;
251
252                 /* volatile entries do not return to cache */
253                 ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
254                 tmp_mc.mc_ndn = e->e_nname;
255                 mc = avl_delete( &mi->mi_cache,
256                                 ( caddr_t )&tmp_mc, monitor_cache_cmp );
257                 ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
258                 ch_free( mc );
259                 
260                 ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );
261                 ldap_pvt_thread_mutex_destroy( &mp->mp_mutex );
262                 ch_free( mp );
263                 e->e_private = NULL;
264                 entry_free( e );
265
266                 return( 0 );
267         }
268         
269         ldap_pvt_thread_mutex_unlock( &mp->mp_mutex );
270
271         return( 0 );
272 }
273