]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/nextid.c
Initial step of index files fix, more tomorrow.
[openldap] / servers / slapd / back-ldbm / nextid.c
1 /* id.c - keep track of the next id to be given out */
2
3 #include "portable.h"
4
5 #include <stdio.h>
6
7 #include <ac/socket.h>
8
9 #ifdef HAVE_SYS_PARAM_H
10 #include <sys/param.h>
11 #endif
12
13 #include "slap.h"
14 #include "back-ldbm.h"
15
16 static ID
17 next_id_read( Backend *be )
18 {
19         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
20         ID      id;
21         char    buf[20];
22         char*   file = li->li_nextid_file; 
23         FILE*   fp;
24
25         if ( (fp = fopen( file, "r" )) == NULL ) {
26                 Debug( LDAP_DEBUG_ANY,
27                     "next_id_read: could not open \"%s\"\n",
28                     file, 0, 0 );
29                 return NOID;
30         }
31
32         if ( fgets( buf, sizeof(buf), fp ) == NULL ) {
33                 Debug( LDAP_DEBUG_ANY,
34                    "next_id_read: could not fgets nextid from \"%s\"\n",
35                     file, 0, 0 );
36                 fclose( fp );
37                 return NOID;
38         }
39
40         id = atol( buf );
41         fclose( fp );
42
43         if(id < 1) {
44                 Debug( LDAP_DEBUG_ANY,
45                         "next_id_read %lu: atol(%s) return non-positive integer\n",
46                         id, buf, 0 );
47                 return NOID;
48         }
49
50         return id;
51 }
52
53 static int
54 next_id_write( Backend *be, ID id )
55 {
56         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
57         char    buf[20];
58         char*   file = li->li_nextid_file; 
59         FILE*   fp;
60         int             rc;
61
62         if ( (fp = fopen( file, "w" )) == NULL ) {
63                 Debug( LDAP_DEBUG_ANY, "next_id_write(%lu): could not open \"%s\"\n",
64                     id, file, 0 );
65                 return -1;
66         } 
67
68         rc = 0;
69
70         if ( fprintf( fp, "%ld\n", id ) == EOF ) {
71                 Debug( LDAP_DEBUG_ANY, "next_id_write(%lu): cannot fprintf\n",
72                     id, 0, 0 );
73                 rc = -1;
74         }
75
76         if( fclose( fp ) != 0 ) {
77                 Debug( LDAP_DEBUG_ANY, "next_id_write %lu: cannot fclose\n",
78                     id, 0, 0 );
79                 rc = -1;
80         }
81
82         return rc;
83 }
84
85 int
86 next_id_save( Backend *be )
87 {
88         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
89         ID id = next_id_get( be );
90         int rc = next_id_write( be, id );
91
92         if (rc == 0) {
93                 li->li_nextid_wrote = id;
94         }
95
96         return rc;
97 }
98
99 ID
100 next_id( Backend *be )
101 {
102         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
103         ID              id;
104
105         ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
106
107         /* first time in here since startup - try to read the nexid */
108         if ( li->li_nextid == NOID ) {
109                 li->li_nextid = next_id_read( be );
110
111                 if ( li->li_nextid == NOID ) {
112                         li->li_nextid = 1;
113                 }
114
115 #if SLAPD_NEXTID_CHUNK > 1
116                 li->li_nextid_wrote = li->li_nextid;
117 #endif
118         }
119
120         id = li->li_nextid++;
121
122 #if SLAPD_NEXTID_CHUNK > 1
123         if ( li->li_nextid > li->li_nextid_wrote ) {
124                 li->li_nextid_wrote += SLAPD_NEXTID_CHUNK;
125                 (void) next_id_write( be, li->li_nextid_wrote );
126         }
127 #else
128         (void) next_id_write( be, li->li_nextid );
129 #endif
130
131         ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
132         return( id );
133 }
134
135 void
136 next_id_return( Backend *be, ID id )
137 {
138 #ifdef SLAPD_NEXTID_RETURN
139         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
140
141         ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
142
143         if ( id != li->li_nextid - 1 ) {
144                 ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
145                 return;
146         }
147
148         li->li_nextid--;
149
150 #if !( SLAPD_NEXTID_CHUCK > 1 )
151         (void) next_id_write( be, li->li_nextid );
152 #endif
153
154         ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
155 #endif
156 }
157
158 ID
159 next_id_get( Backend *be )
160 {
161         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
162         ID              id;
163
164         ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
165
166         /* first time in here since startup - try to read the nexid */
167         if ( li->li_nextid == NOID ) {
168                 li->li_nextid = next_id_read( be );
169
170                 if ( li->li_nextid == NOID ) {
171                         li->li_nextid = 1;
172                 }
173
174 #if SLAPD_NEXTID_CHUNK > 1
175                 li->li_nextid_wrote = li->li_nextid;
176 #endif
177         }
178
179         id = li->li_nextid;
180
181         ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
182
183         return( id );
184 }