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 )
20 * binary search of id in ids
21 * if found, returns position of id
22 * if not found, returns first postion greater than id
31 cursor = base + pivot;
32 val = IDL_CMP( id, ids[cursor + 1] );
37 } else if ( val > 0 ) {
53 static int idl_insert( ID *ids, ID id )
55 int x = bdb_idl_search( ids, id );
67 } else if ( ++ids[0] >= BDB_IDL_DB_MAX ) {
72 AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) );
80 static int idl_delete( ID *ids, ID id )
82 int x = bdb_idl_search( ids, id );
84 if( x == 0 || ids[x] != id ) {
88 } else if ( --ids[0] == 0 ) {
89 if( x != 1 ) return -1;
92 AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) );
107 ID ids[BDB_IDL_DB_SIZE];
110 assert( id != NOID );
113 data.ulen = sizeof( ids );
114 data.flags = DB_DBT_USERMEM;
116 /* fetch the key and grab a write lock */
117 rc = db->get( db, tid, key, &data, DB_RMW );
119 if( rc == DB_NOTFOUND ) {
122 data.size = 2 * sizeof( ID );
124 } else if ( rc != 0 ) {
125 Debug( LDAP_DEBUG_ANY,
126 "=> bdb_idl_insert_key: get failed: %s (%d)\n",
127 db_strerror(rc), rc, 0 );
130 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
131 /* size not multiple of ID size */
132 Debug( LDAP_DEBUG_ANY,
133 "=> bdb_idl_insert_key: odd size: expected %ld multiple, got %ld\n",
134 (long) sizeof( ID ), (long) data.size, 0 );
137 } else if ( BDB_IS_ALLIDS(ids) ) {
140 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
142 Debug( LDAP_DEBUG_ANY,
143 "=> bdb_idl_insert_key: get size mismatch: expected %ld, got %ld\n",
144 (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 );
148 rc = idl_insert( ids, id );
150 if( rc != 0 ) return rc;
152 data.size = (ids[0]+1) * sizeof( ID );
156 rc = db->put( db, tid, key, &data, 0 );
159 Debug( LDAP_DEBUG_ANY,
160 "=> bdb_idl_insert_key: get failed: %s (%d)\n",
161 db_strerror(rc), rc, 0 );
175 ID ids[BDB_IDL_DB_SIZE];
178 assert( id != NOID );
181 data.ulen = sizeof( ids );
182 data.flags = DB_DBT_USERMEM;
184 /* fetch the key and grab a write lock */
185 rc = db->get( db, tid, key, &data, DB_RMW );
188 Debug( LDAP_DEBUG_ANY,
189 "=> bdb_idl_delete_key: get failed: %s (%d)\n",
190 db_strerror(rc), rc, 0 );
193 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
194 /* size not multiple of ID size */
195 Debug( LDAP_DEBUG_ANY,
196 "=> bdb_idl_delete_key: odd size: expected %ld multiple, got %ld\n",
197 (long) sizeof( ID ), (long) data.size, 0 );
200 } else if ( BDB_IS_ALLIDS(ids) ) {
203 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
205 Debug( LDAP_DEBUG_ANY,
206 "=> bdb_idl_delete_key: get size mismatch: expected %ld, got %ld\n",
207 (long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 );
211 rc = idl_delete( ids, id );
213 if( rc != 0 ) return rc;
215 if( BDB_IS_ALLIDS(ids) ) {
217 rc = db->del( db, tid, key, 0 );
219 Debug( LDAP_DEBUG_ANY,
220 "=> bdb_idl_delete_key: delete failed: %s (%d)\n",
221 db_strerror(rc), rc, 0 );
226 data.size = (ids[0]+1) * sizeof( ID );
230 rc = db->put( db, tid, key, &data, 0 );
233 Debug( LDAP_DEBUG_ANY,
234 "=> bdb_idl_delete_key: put failed: %s (%d)\n",
235 db_strerror(rc), rc, 0 );