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 ) )
17 int bdb_idl_search( ID *ids, ID id )
19 #if BDB_IDL_BINARY_SEARCH
21 * binary search of id in ids
22 * if found, returns position of id
23 * if not found, returns first postion greater than id
32 cursor = base + pivot;
33 val = IDL_CMP( id, ids[cursor + 1] );
38 } else if ( val > 0 ) {
54 /* (reverse) linear search */
56 for( i=ids[0]; i; i-- ) {
65 static int idl_insert( ID *ids, ID id )
67 int x = bdb_idl_search( ids, id );
81 if ( ++ids[0] >= BDB_IDL_DB_MAX ) {
86 AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) );
94 static int idl_delete( ID *ids, ID id )
96 int x = bdb_idl_search( ids, id );
105 if( x > ids[0] || ids[x] != id ) {
109 } else if ( --ids[0] == 0 ) {
115 AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) );
130 ID ids[BDB_IDL_DB_SIZE];
133 assert( id != NOID );
136 data.ulen = sizeof( ids );
137 data.flags = DB_DBT_USERMEM;
139 /* fetch the key and grab a write lock */
140 rc = db->get( db, tid, key, &data, DB_RMW );
142 if( rc == DB_NOTFOUND ) {
145 data.size = 2 * sizeof( ID );
147 } else if ( rc != 0 ) {
148 Debug( LDAP_DEBUG_ANY,
149 "=> bdb_idl_insert_key: get failed: %s (%d)\n",
150 db_strerror(rc), rc, 0 );
153 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
154 /* size not multiple of ID size */
155 Debug( LDAP_DEBUG_ANY,
156 "=> bdb_idl_insert_key: odd size: expected %ld multiple, got %ld\n",
157 (long) sizeof( ID ), (long) data.size, 0 );
160 } else if ( BDB_IS_ALLIDS(ids) ) {
163 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
165 Debug( LDAP_DEBUG_ANY,
166 "=> bdb_idl_insert_key: get size mismatch: expected %ld, got %ld\n",
167 (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 );
171 rc = idl_insert( ids, id );
174 Debug( LDAP_DEBUG_ANY,
175 "=> bdb_idl_insert_key: idl_insert failed (%d)\n",
180 if( BDB_IS_ALLIDS( ids ) ) {
181 data.size = sizeof( ID );
183 data.size = (ids[0]+1) * sizeof( ID );
188 rc = db->put( db, tid, key, &data, 0 );
191 Debug( LDAP_DEBUG_ANY,
192 "=> bdb_idl_insert_key: get failed: %s (%d)\n",
193 db_strerror(rc), rc, 0 );
207 ID ids[BDB_IDL_DB_SIZE];
210 assert( id != NOID );
213 data.ulen = sizeof( ids );
214 data.flags = DB_DBT_USERMEM;
216 /* fetch the key and grab a write lock */
217 rc = db->get( db, tid, key, &data, DB_RMW );
220 Debug( LDAP_DEBUG_ANY,
221 "=> bdb_idl_delete_key: get failed: %s (%d)\n",
222 db_strerror(rc), rc, 0 );
225 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
226 /* size not multiple of ID size */
227 Debug( LDAP_DEBUG_ANY,
228 "=> bdb_idl_delete_key: odd size: expected %ld multiple, got %ld\n",
229 (long) sizeof( ID ), (long) data.size, 0 );
232 } else if ( BDB_IS_ALLIDS(ids) ) {
235 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
237 Debug( LDAP_DEBUG_ANY,
238 "=> bdb_idl_delete_key: get size mismatch: expected %ld, got %ld\n",
239 (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 );
243 rc = idl_delete( ids, id );
246 Debug( LDAP_DEBUG_ANY,
247 "=> bdb_idl_insert_key: idl_insert failed (%d)\n",
254 rc = db->del( db, tid, key, 0 );
256 Debug( LDAP_DEBUG_ANY,
257 "=> bdb_idl_delete_key: delete failed: %s (%d)\n",
258 db_strerror(rc), rc, 0 );
263 data.size = (ids[0]+1) * sizeof( ID );
267 rc = db->put( db, tid, key, &data, 0 );
270 Debug( LDAP_DEBUG_ANY,
271 "=> bdb_idl_delete_key: put failed: %s (%d)\n",
272 db_strerror(rc), rc, 0 );