]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
New dn2id format with base/one/subtree indices (ldbm/bdb2)
[openldap] / servers / slapd / back-ldbm / dn2id.c
1 /* dn2id.c - routines to deal with the dn2id index */
2 /*
3  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/string.h>
12 #include <ac/socket.h>
13
14 #include "slap.h"
15 #include "back-ldbm.h"
16 #include "proto-back-ldbm.h"
17
18 int
19 dn2id_add(
20     Backend     *be,
21     char        *dn,
22     ID          id
23 )
24 {
25         int             rc, flags;
26         DBCache *db;
27         Datum           key, data;
28         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
29
30         Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
31
32         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
33             == NULL ) {
34                 Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
35                     LDBM_SUFFIX, 0, 0 );
36                 return( -1 );
37         }
38
39         ldbm_datum_init( key );
40         key.dsize = strlen( dn ) + 2;
41         key.dptr = ch_malloc( key.dsize );
42         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
43
44         ldbm_datum_init( data );
45         data.dptr = (char *) &id;
46         data.dsize = sizeof(ID);
47
48         flags = LDBM_INSERT;
49         if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
50
51         rc = ldbm_cache_store( db, key, data, flags );
52
53         free( key.dptr );
54
55         if ( rc != -1 ) {
56                 char *pdn = dn_parent( NULL, dn );
57
58                 if( pdn != NULL ) {
59                         ldbm_datum_init( key );
60                         key.dsize = strlen( pdn ) + 2;
61                         key.dptr = ch_malloc( key.dsize );
62                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
63                         rc = idl_insert_key( be, db, key, id );
64                         free( key.dptr );
65                 }
66         }
67
68         if ( rc != -1 ) {
69                 char **subtree = dn_subtree( NULL, dn );
70
71                 if( subtree != NULL ) {
72                         int i;
73                         for( i=0; subtree[i] != NULL; i++ ) {
74                                 ldbm_datum_init( key );
75                                 key.dsize = strlen( subtree[i] ) + 2;
76                                 key.dptr = ch_malloc( key.dsize );
77                                 sprintf( key.dptr, "%c%s",
78                                         DN_SUBTREE_PREFIX, subtree[i] );
79
80                                 rc = idl_insert_key( be, db, key, id );
81
82                                 free( key.dptr );
83
84                                 if(rc == -1) break;
85                         }
86
87                         charray_free( subtree );
88                 }
89
90         }
91
92         ldbm_cache_close( be, db );
93
94         Debug( LDAP_DEBUG_TRACE, "<= dn2id_add %d\n", rc, 0, 0 );
95         return( rc );
96 }
97
98 ID
99 dn2id(
100     Backend     *be,
101     char        *dn
102 )
103 {
104         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
105         DBCache *db;
106         ID              id;
107         Datum           key, data;
108
109         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
110
111         /* first check the cache */
112         if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
113                 Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", id,
114                         0, 0 );
115                 return( id );
116         }
117
118         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
119                 == NULL ) {
120                 Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
121                         LDBM_SUFFIX, 0, 0 );
122                 return( NOID );
123         }
124
125         ldbm_datum_init( key );
126
127         key.dsize = strlen( dn ) + 2;
128         key.dptr = ch_malloc( key.dsize );
129         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
130
131         data = ldbm_cache_fetch( db, key );
132
133         ldbm_cache_close( be, db );
134
135         free( key.dptr );
136
137         if ( data.dptr == NULL ) {
138                 Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
139                 return( NOID );
140         }
141
142         (void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
143
144         ldbm_datum_free( db->dbc_db, data );
145
146         Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", id, 0, 0 );
147         return( id );
148 }
149
150 ID_BLOCK *
151 dn2idl(
152     Backend     *be,
153     char        *dn,
154         int             prefix
155 )
156 {
157         DBCache *db;
158         Datum           key;
159         ID_BLOCK        *idl;
160
161         Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
162
163         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
164                 == NULL ) {
165                 Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n",
166                         LDBM_SUFFIX, 0, 0 );
167                 return NULL;
168         }
169
170         ldbm_datum_init( key );
171
172         key.dsize = strlen( dn ) + 2;
173         key.dptr = ch_malloc( key.dsize );
174         sprintf( key.dptr, "%c%s", prefix, dn );
175
176         idl = idl_fetch( be, db, key );
177
178         ldbm_cache_close( be, db );
179
180         free( key.dptr );
181
182         return( idl );
183 }
184
185
186 int
187 dn2id_delete(
188     Backend     *be,
189     char        *dn
190 )
191 {
192         DBCache *db;
193         Datum           key;
194         int             rc;
195
196         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\" )\n", dn, 0, 0 );
197
198         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
199             == NULL ) {
200                 Debug( LDAP_DEBUG_ANY,
201                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
202                     0, 0 );
203                 return( -1 );
204         }
205
206         ldbm_datum_init( key );
207
208         key.dsize = strlen( dn ) + 2;
209         key.dptr = ch_malloc( key.dsize );
210         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
211
212         rc = ldbm_cache_delete( db, key );
213
214         free( key.dptr );
215
216         ldbm_cache_close( be, db );
217
218         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
219         return( rc );
220 }
221
222 /*
223  * dn2entry - look up dn in the cache/indexes and return the corresponding
224  * entry.
225  */
226
227 Entry *
228 dn2entry_rw(
229     Backend     *be,
230     char        *dn,
231     Entry       **matched,
232     int         rw
233 )
234 {
235         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
236         ID              id;
237         Entry           *e = NULL;
238         char            *pdn;
239
240         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
241                 rw ? "w" : "r", dn, 0);
242
243         if( matched != NULL ) {
244                 /* caller cares about match */
245                 *matched = NULL;
246         }
247
248         if ( (id = dn2id( be, dn )) != NOID &&
249                 (e = id2entry_rw( be, id, rw )) != NULL )
250         {
251                 return( e );
252         }
253
254         if ( id != NOID ) {
255                 Debug(LDAP_DEBUG_ANY,
256                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
257                         rw ? "w" : "r", id, dn);
258                 /* must have been deleted from underneath us */
259                 /* treat as if NOID was found */
260         }
261
262         /* caller doesn't care about match */
263         if( matched == NULL ) return NULL;
264
265         /* entry does not exist - see how much of the dn does exist */
266         /* dn_parent checks returns NULL if dn is suffix */
267         if ( (pdn = dn_parent( be, dn )) != NULL ) {
268                 /* get entry with reader lock */
269                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
270                         *matched = e;
271                 }
272                 free( pdn );
273         }
274
275         return NULL;
276 }
277