]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/id2entry.c
Merged in per cache entry reader/writer locks from OPENLDAP_DEVEL_THREAD
[openldap] / servers / slapd / back-ldbm / id2entry.c
1 /* id2entry.c - routines to deal with the id2entry index */
2
3 #include <stdio.h>
4 #include <sys/types.h>
5 #include <sys/socket.h>
6 #include "slap.h"
7 #include "back-ldbm.h"
8
9 extern struct dbcache   *ldbm_cache_open();
10 extern Datum            ldbm_cache_fetch();
11 extern char             *dn_parent();
12 extern Entry            *str2entry();
13 extern char             *entry2str();
14 extern pthread_mutex_t  entry2str_mutex;
15
16 int
17 id2entry_add( Backend *be, Entry *e )
18 {
19         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
20         struct dbcache  *db;
21         Datum           key, data;
22         int             len, rc, flags;
23
24 #ifdef LDBM_USE_DB2
25         memset( &key, 0, sizeof( key ) );
26         memset( &data, 0, sizeof( data ) );
27 #endif
28
29         Debug( LDAP_DEBUG_TRACE, "=> id2entry_add( %d, \"%s\" )\n", e->e_id,
30             e->e_dn, 0 );
31
32         if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT ))
33             == NULL ) {
34                 Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n",
35                     LDBM_SUFFIX, 0, 0 );
36                 return( -1 );
37         }
38
39         key.dptr = (char *) &e->e_id;
40         key.dsize = sizeof(ID);
41
42         pthread_mutex_lock( &entry2str_mutex );
43         data.dptr = entry2str( e, &len, 1 );
44         data.dsize = len + 1;
45
46         /* store it */
47         flags = LDBM_REPLACE;
48         if ( li->li_flush_wrt ) flags != LDBM_SYNC;
49         rc = ldbm_cache_store( db, key, data, flags );
50
51         pthread_mutex_unlock( &entry2str_mutex );
52
53         ldbm_cache_close( be, db );
54         (void) cache_add_entry_lock( &li->li_cache, e, 0 );
55
56         Debug( LDAP_DEBUG_TRACE, "<= id2entry_add %d\n", rc, 0, 0 );
57
58         /* XXX should entries be born locked, i.e. apply writer lock here? */
59         return( rc );
60 }
61
62 int
63 id2entry_delete( Backend *be, Entry *e )
64 {
65         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
66         struct dbcache  *db;
67         Datum           key;
68         int             rc;
69
70         Debug( LDAP_DEBUG_TRACE, "=> id2entry_delete( %d, \"%s\" )\n", e->e_id,
71             e->e_dn, 0 );
72
73         /* XXX - check for writer lock - should also check no reader pending */
74         assert(pthread_rdwr_wchk_np(&e->e_rdwr));
75
76 #ifdef LDBM_USE_DB2
77         memset( &key, 0, sizeof( key ) );
78 #endif
79
80         /* XXX - check for writer lock - should also check no reader pending */
81         Debug (LDAP_DEBUG_TRACE,
82                 "rdwr_Xchk: readers_reading: %d writer_writing: %d\n",
83                 e->e_rdwr.readers_reading, e->e_rdwr.writer_writing, 0);
84  
85         if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT ))
86                 == NULL ) {
87                 Debug( LDAP_DEBUG_ANY, "Could not open/create id2entry%s\n",
88                     LDBM_SUFFIX, 0, 0 );
89                 return( -1 );
90         }
91
92         if ( cache_delete_entry( &li->li_cache, e ) != 0 ) {
93                 Debug( LDAP_DEBUG_ANY, "could not delete %d (%s) from cache\n",
94                     e->e_id, e->e_dn, 0 );
95         }
96
97         key.dptr = (char *) &e->e_id;
98         key.dsize = sizeof(ID);
99
100         rc = ldbm_cache_delete( db, key );
101
102         ldbm_cache_close( be, db );
103
104         Debug( LDAP_DEBUG_TRACE, "<= id2entry_delete %d\n", rc, 0, 0 );
105         return( rc );
106 }
107
108 /* XXX returns entry with reader/writer lock */
109 Entry *
110 id2entry( Backend *be, ID id, int rw )
111 {
112         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
113         struct dbcache  *db;
114         Datum           key, data;
115         Entry           *e;
116
117 #ifdef LDBM_USE_DB2
118         memset( &key, 0, sizeof( key ) );
119         memset( &data, 0, sizeof( data ) );
120 #endif
121
122         Debug( LDAP_DEBUG_TRACE, "=> id2entry_%s( %ld )\n",
123                 rw ? "w" : "r", id, 0 );
124
125         if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) {
126                 Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s 0x%x (cache)\n",
127                         rw ? "w" : "r", e, 0 );
128                 return( e );
129         }
130
131         if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT ))
132                 == NULL ) {
133                 Debug( LDAP_DEBUG_ANY, "Could not open id2entry%s\n",
134                     LDBM_SUFFIX, 0, 0 );
135                 return( NULL );
136         }
137
138         key.dptr = (char *) &id;
139         key.dsize = sizeof(ID);
140
141         data = ldbm_cache_fetch( db, key );
142
143         if ( data.dptr == NULL ) {
144                 Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) not found\n",
145                         rw ? "w" : "r", id, 0 );
146                 ldbm_cache_close( be, db );
147                 return( NULL );
148         }
149
150         e = str2entry( data.dptr );
151
152         ldbm_datum_free( db->dbc_db, data );
153         ldbm_cache_close( be, db );
154
155         if ( e == NULL ) {
156                 Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld )  (failed)\n",
157                         rw ? "w" : "r", id, 0 );
158                 return( NULL );
159         }
160
161         /* acquire required reader/writer lock */
162         if (entry_rdwr_lock(e, rw)) {
163                 /* XXX set DELETE flag?? */
164                 entry_free(e);
165                 return(NULL);
166         }
167
168         e->e_id = id;
169         (void) cache_add_entry_lock( &li->li_cache, e, 0 );
170
171         Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (disk)\n",
172                 rw ? "w" : "r", id, 0 );
173         return( e );
174 }
175
176 Entry *
177 id2entry_r( Backend *be, ID id )
178 {
179         return( id2entry( be, id, 0 ) );
180 }
181
182 Entry *
183 id2entry_2( Backend *be, ID id )
184 {
185         return( id2entry( be, id, 1 ) );
186 }
187