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
12 #include <ac/string.h>
13 #include <ac/socket.h>
17 #define BDB_IDL_SIZE (1<<16)
18 #define BDB_IDL_MAX (BDB_IDL_SIZE-16)
19 #define BDB_IDL_ALLOC (BDB_IDL_MAX * sizeof(ID))
21 #define BDB_IS_ALLIDS(ids) ((ids)[0] == NOID)
23 static int idl_search( ID *ids, ID id )
25 /* we should replace this a binary search as ids is sorted */
29 for( i = 1; i <= n; i++ ) {
38 static int idl_insert( ID *ids, ID id )
40 int x = idl_search( ids, id );
52 } else if ( ++ids[0] >= BDB_IDL_MAX ) {
57 AC_MEMCPY( &ids[x+1], &ids[x], (ids[0]-x) * sizeof(ID) );
65 static int idl_delete( ID *ids, ID id )
67 int x = idl_search( ids, id );
69 if( x == 0 || ids[x] != id ) {
73 } else if ( --ids[0] == 0 ) {
74 if( x != 1 ) return -1;
77 AC_MEMCPY( &ids[x], &ids[x+1], (1+ids[0]-x) * sizeof(ID) );
98 data.ulen = sizeof( ids );
99 data.flags = DB_DBT_USERMEM;
101 /* fetch the key and grab a write lock */
102 rc = db->get( db, tid, key, &data, DB_RMW );
104 if( rc == DB_NOTFOUND ) {
107 data.size = 2 * sizeof( ID );
109 } else if ( rc != 0 ) {
112 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
113 /* size not multiple of ID size */
116 } else if ( BDB_IS_ALLIDS(ids) ) {
119 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
124 rc = idl_insert( ids, id );
126 if( rc != 0 ) return rc;
128 data.size = (ids[0]+1) * sizeof( ID );
132 rc = db->put( db, tid, key, &data, 0 );
146 ID ids[BDB_IDL_SIZE];
149 assert( id != NOID );
152 data.ulen = sizeof( ids );
153 data.flags = DB_DBT_USERMEM;
155 /* fetch the key and grab a write lock */
156 rc = db->get( db, tid, key, &data, DB_RMW );
161 } else if ( data.size == 0 || data.size % sizeof( ID ) ) {
162 /* size not multiple of ID size */
165 } else if ( BDB_IS_ALLIDS(ids) ) {
168 } else if ( data.size != (1 + ids[0]) * sizeof( ID ) ) {
173 rc = idl_delete( ids, id );
175 if( rc != 0 ) return rc;
177 if( BDB_IS_ALLIDS(ids) ) {
179 rc = db->del( db, tid, key, 0 );
183 data.size = (ids[0]+1) * sizeof( ID );
187 rc = db->put( db, tid, key, &data, 0 );