1 /* idl.c - ldap id list handling routines */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
11 #include <ac/string.h>
15 #define IDL_CMP(x,y) ( x < y ? -1 : ( x > y ? 1 : 0 ) )
19 void idl_dump( ID *ids )
21 if( BDB_IDL_IS_RANGE( ids ) ) {
22 Debug( LDAP_DEBUG_ANY,
23 "IDL: range %ld - %ld\n", (long) ids[0], 0, 0 );
27 Debug( LDAP_DEBUG_ANY, "IDL: size %ld", (long) ids[0], 0, 0 );
29 for( i=1; i<=ids[0]; i++ ) {
31 Debug( LDAP_DEBUG_ANY, "\n", 0, 0, 0 );
33 Debug( LDAP_DEBUG_ANY, " %02lx", ids[i], 0, 0 );
36 Debug( LDAP_DEBUG_ANY, "\n", 0, 0, 0 );
41 unsigned bdb_idl_search( ID *ids, ID id )
43 #undef IDL_BINARY_SEARCH
44 #ifdef IDL_BINARY_SEARCH
46 * binary search of id in ids
47 * if found, returns position of id
48 * if not found, returns first postion greater than id
57 cursor = base + pivot;
58 val = IDL_CMP( id, ids[cursor + 1] );
63 } else if ( val > 0 ) {
79 /* (reverse) linear search */
81 for( i=ids[0]; i; i-- ) {
90 static int idl_insert( ID *ids, ID id )
92 unsigned x = bdb_idl_search( ids, id );
95 Debug( LDAP_DEBUG_ANY, "insert: %04lx at %d\n", id, x, 0 );
106 if ( x <= ids[0] && ids[x] == id ) {
111 if ( ++ids[0] >= BDB_IDL_DB_MAX ) {
114 ids[2] = ids[ids[0]-1];
115 } else if ( ids[ids[0]-1] < id ) {
118 ids[2] = ids[ids[0]-1];
124 AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) );
135 static int idl_delete( ID *ids, ID id )
137 unsigned x = bdb_idl_search( ids, id );
140 Debug( LDAP_DEBUG_ANY, "delete: %04lx at %d\n", id, x, 0 );
151 if( x > ids[0] || ids[x] != id ) {
155 } else if ( --ids[0] == 0 ) {
161 AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) );
180 ID ids[BDB_IDL_DB_SIZE];
183 /* for printable keys only */
184 Debug( LDAP_DEBUG_ARGS,
185 "=> bdb_idl_insert_key: %s %ld\n",
186 key->data, (long) id, 0 );
188 assert( id != NOID );
191 data.ulen = sizeof( ids );
192 data.flags = DB_DBT_USERMEM;
194 /* fetch the key for read/modify/write */
195 rc = db->get( db, tid, key, &data, DB_RMW );
197 if( rc == DB_NOTFOUND ) {
200 data.size = 2 * sizeof( ID );
202 } else if ( rc != 0 ) {
203 Debug( LDAP_DEBUG_ANY,
204 "=> bdb_idl_insert_key: get failed: %s (%d)\n",
205 db_strerror(rc), rc, 0 );
208 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
209 /* size not multiple of ID size */
210 Debug( LDAP_DEBUG_ANY,
211 "=> bdb_idl_insert_key: odd size: expected %ld multiple, got %ld\n",
212 (long) sizeof( ID ), (long) data.size, 0 );
215 } else if ( BDB_IDL_IS_RANGE(ids) ) {
218 } else if ( ids[2] > id ) {
224 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
226 Debug( LDAP_DEBUG_ANY,
227 "=> bdb_idl_insert_key: get size mismatch: expected %ld, got %ld\n",
228 (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 );
232 rc = idl_insert( ids, id );
235 Debug( LDAP_DEBUG_ANY,
236 "=> bdb_idl_insert_key: idl_insert failed (%d)\n",
241 if( BDB_IDL_IS_RANGE( ids ) ) {
242 data.size = BDB_IDL_RANGE_SIZE;
244 data.size = (ids[0]+1) * sizeof( ID );
249 rc = db->put( db, tid, key, &data, 0 );
252 Debug( LDAP_DEBUG_ANY,
253 "=> bdb_idl_insert_key: get failed: %s (%d)\n",
254 db_strerror(rc), rc, 0 );
268 ID ids[BDB_IDL_DB_SIZE];
271 /* for printable keys only */
272 Debug( LDAP_DEBUG_ARGS,
273 "=> bdb_idl_delete_key: %s %ld\n",
274 key->data, (long) id, 0 );
276 assert( id != NOID );
279 data.ulen = sizeof( ids );
280 data.flags = DB_DBT_USERMEM;
282 /* fetch the key for read/modify/write */
283 rc = db->get( db, tid, key, &data, DB_RMW );
286 Debug( LDAP_DEBUG_ANY,
287 "=> bdb_idl_delete_key: get failed: %s (%d)\n",
288 db_strerror(rc), rc, 0 );
291 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
292 /* size not multiple of ID size */
293 Debug( LDAP_DEBUG_ANY,
294 "=> bdb_idl_delete_key: odd size: expected %ld multiple, got %ld\n",
295 (long) sizeof( ID ), (long) data.size, 0 );
298 } else if ( BDB_IDL_IS_RANGE(ids) ) {
301 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
303 Debug( LDAP_DEBUG_ANY,
304 "=> bdb_idl_delete_key: get size mismatch: expected %ld, got %ld\n",
305 (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 );
309 rc = idl_delete( ids, id );
312 Debug( LDAP_DEBUG_ANY,
313 "=> bdb_idl_delete_key: idl_delete failed (%d)\n",
320 rc = db->del( db, tid, key, 0 );
322 Debug( LDAP_DEBUG_ANY,
323 "=> bdb_idl_delete_key: delete failed: %s (%d)\n",
324 db_strerror(rc), rc, 0 );
329 data.size = (ids[0]+1) * sizeof( ID );
333 rc = db->put( db, tid, key, &data, 0 );
336 Debug( LDAP_DEBUG_ANY,
337 "=> bdb_idl_delete_key: put failed: %s (%d)\n",
338 db_strerror(rc), rc, 0 );