⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idl.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
# if BDB_IDL_DB_SIZE < 4096#   define BDB_ENOUGH 2048# else#	define BDB_ENOUGH 1# endif#endif	ID buf[BDB_IDL_DB_SIZE*BDB_ENOUGH];	char keybuf[16];	Debug( LDAP_DEBUG_ARGS,		"bdb_idl_fetch_key: %s\n", 		bdb_show_key( key, keybuf ), 0, 0 );	assert( ids != NULL );	if ( saved_cursor && *saved_cursor ) {		opflag = DB_NEXT;	} else if ( get_flag == LDAP_FILTER_GE ) {		opflag = DB_SET_RANGE;	} else if ( get_flag == LDAP_FILTER_LE ) {		opflag = DB_FIRST;	} else {		opflag = DB_SET;	}	/* only non-range lookups can use the IDL cache */	if ( bdb->bi_idl_cache_size && opflag == DB_SET ) {		rc = bdb_idl_cache_get( bdb, db, key, ids );		if ( rc != LDAP_NO_SUCH_OBJECT ) return rc;	}	DBTzero( &data );	data.data = buf;	data.ulen = sizeof(buf);	data.flags = DB_DBT_USERMEM;	/* If we're not reusing an existing cursor, get a new one */	if( opflag != DB_NEXT ) {		rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );		if( rc != 0 ) {			Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "				"cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 );			return rc;		}	} else {		cursor = *saved_cursor;	}		/* If this is a LE lookup, save original key so we can determine	 * when to stop. If this is a GE lookup, save the key since it	 * will be overwritten.	 */	if ( get_flag == LDAP_FILTER_LE || get_flag == LDAP_FILTER_GE ) {		DBTzero( &key2 );		key2.flags = DB_DBT_USERMEM;		key2.ulen = sizeof(keybuf);		key2.data = keybuf;		key2.size = key->size;		AC_MEMCPY( keybuf, key->data, key->size );		kptr = &key2;	} else {		kptr = key;	}	len = key->size;	rc = cursor->c_get( cursor, kptr, &data, flags | opflag );	/* skip presence key on range inequality lookups */	while (rc == 0 && kptr->size != len) {		rc = cursor->c_get( cursor, kptr, &data, flags | DB_NEXT_NODUP );	}	/* If we're doing a LE compare and the new key is greater than	 * our search key, we're done	 */	if (rc == 0 && get_flag == LDAP_FILTER_LE && memcmp( kptr->data,		key->data, key->size ) > 0 ) {		rc = DB_NOTFOUND;	}	if (rc == 0) {		i = ids;		while (rc == 0) {			u_int8_t *j;			DB_MULTIPLE_INIT( ptr, &data );			while (ptr) {				DB_MULTIPLE_NEXT(ptr, &data, j, len);				if (j) {					++i;					BDB_DISK2ID( j, i );				}			}			rc = cursor->c_get( cursor, key, &data, flags | DB_NEXT_DUP );		}		if ( rc == DB_NOTFOUND ) rc = 0;		ids[0] = i - ids;		/* On disk, a range is denoted by 0 in the first element */		if (ids[1] == 0) {			if (ids[0] != BDB_IDL_RANGE_SIZE) {				Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "					"range size mismatch: expected %d, got %ld\n",					BDB_IDL_RANGE_SIZE, ids[0], 0 );				cursor->c_close( cursor );				return -1;			}			BDB_IDL_RANGE( ids, ids[2], ids[3] );		}		data.size = BDB_IDL_SIZEOF(ids);	}	if ( saved_cursor && rc == 0 ) {		if ( !*saved_cursor )			*saved_cursor = cursor;		rc2 = 0;	}	else		rc2 = cursor->c_close( cursor );	if (rc2) {		Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "			"close failed: %s (%d)\n", db_strerror(rc2), rc2, 0 );		return rc2;	}	if( rc == DB_NOTFOUND ) {		return rc;	} else if( rc != 0 ) {		Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "			"get failed: %s (%d)\n",			db_strerror(rc), rc, 0 );		return rc;	} else if ( data.size == 0 || data.size % sizeof( ID ) ) {		/* size not multiple of ID size */		Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "			"odd size: expected %ld multiple, got %ld\n",			(long) sizeof( ID ), (long) data.size, 0 );		return -1;	} else if ( data.size != BDB_IDL_SIZEOF(ids) ) {		/* size mismatch */		Debug( LDAP_DEBUG_ANY, "=> bdb_idl_fetch_key: "			"get size mismatch: expected %ld, got %ld\n",			(long) ((1 + ids[0]) * sizeof( ID )), (long) data.size, 0 );		return -1;	}	if ( bdb->bi_idl_cache_max_size ) {		bdb_idl_cache_put( bdb, db, key, ids, rc );	}	return rc;}intbdb_idl_insert_key(	BackendDB	*be,	DB			*db,	DB_TXN		*tid,	DBT			*key,	ID			id ){	struct bdb_info *bdb = (struct bdb_info *) be->be_private;	int	rc;	DBT data;	DBC *cursor;	ID lo, hi, nlo, nhi, nid;	char *err;	{		char buf[16];		Debug( LDAP_DEBUG_ARGS,			"bdb_idl_insert_key: %lx %s\n", 			(long) id, bdb_show_key( key, buf ), 0 );	}	assert( id != NOID );	if ( bdb->bi_idl_cache_size ) {		bdb_idl_cache_del( bdb, db, key );	}	DBTzero( &data );	data.size = sizeof( ID );	data.ulen = data.size;	data.flags = DB_DBT_USERMEM;	BDB_ID2DISK( id, &nid );	rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );	if ( rc != 0 ) {		Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: "			"cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 );		return rc;	}	data.data = &nlo;	/* Fetch the first data item for this key, to see if it	 * exists and if it's a range.	 */	rc = cursor->c_get( cursor, key, &data, DB_SET );	err = "c_get";	if ( rc == 0 ) {		if ( nlo != 0 ) {			/* not a range, count the number of items */			db_recno_t count;			rc = cursor->c_count( cursor, &count, 0 );			if ( rc != 0 ) {				err = "c_count";				goto fail;			}			if ( count >= BDB_IDL_DB_MAX ) {			/* No room, convert to a range */				DBT key2 = *key;				db_recno_t i;				key2.dlen = key2.ulen;				key2.flags |= DB_DBT_PARTIAL;				BDB_DISK2ID( &nlo, &lo );				data.data = &nhi;				rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_NODUP );				if ( rc != 0 && rc != DB_NOTFOUND ) {					err = "c_get next_nodup";					goto fail;				}				if ( rc == DB_NOTFOUND ) {					rc = cursor->c_get( cursor, key, &data, DB_LAST );					if ( rc != 0 ) {						err = "c_get last";						goto fail;					}				} else {					rc = cursor->c_get( cursor, key, &data, DB_PREV );					if ( rc != 0 ) {						err = "c_get prev";						goto fail;					}				}				BDB_DISK2ID( &nhi, &hi );				/* Update hi/lo if needed, then delete all the items				 * between lo and hi				 */				if ( id < lo ) {					lo = id;					nlo = nid;				} else if ( id > hi ) {					hi = id;					nhi = nid;				}				data.data = &nid;				/* Don't fetch anything, just position cursor */				data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;				data.dlen = data.ulen = 0;				rc = cursor->c_get( cursor, key, &data, DB_SET );				if ( rc != 0 ) {					err = "c_get 2";					goto fail;				}				rc = cursor->c_del( cursor, 0 );				if ( rc != 0 ) {					err = "c_del range1";					goto fail;				}				/* Delete all the records */				for ( i=1; i<count; i++ ) {					rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_DUP );					if ( rc != 0 ) {						err = "c_get next_dup";						goto fail;					}					rc = cursor->c_del( cursor, 0 );					if ( rc != 0 ) {						err = "c_del range";						goto fail;					}				}				/* Store the range marker */				data.size = data.ulen = sizeof(ID);				data.flags = DB_DBT_USERMEM;				nid = 0;				rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );				if ( rc != 0 ) {					err = "c_put range";					goto fail;				}				nid = nlo;				rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );				if ( rc != 0 ) {					err = "c_put lo";					goto fail;				}				nid = nhi;				rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );				if ( rc != 0 ) {					err = "c_put hi";					goto fail;				}			} else {			/* There's room, just store it */				goto put1;			}		} else {			/* It's a range, see if we need to rewrite			 * the boundaries			 */			hi = id;			data.data = &nlo;			rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );			if ( rc != 0 ) {				err = "c_get lo";				goto fail;			}			BDB_DISK2ID( &nlo, &lo );			if ( id > lo ) {				data.data = &nhi;				rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );				if ( rc != 0 ) {					err = "c_get hi";					goto fail;				}				BDB_DISK2ID( &nhi, &hi );			}			if ( id < lo || id > hi ) {				/* Delete the current lo/hi */				rc = cursor->c_del( cursor, 0 );				if ( rc != 0 ) {					err = "c_del";					goto fail;				}				data.data = &nid;				rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );				if ( rc != 0 ) {					err = "c_put lo/hi";					goto fail;				}			}		}	} else if ( rc == DB_NOTFOUND ) {put1:		data.data = &nid;		rc = cursor->c_put( cursor, key, &data, DB_NODUPDATA );		/* Don't worry if it's already there */		if ( rc != 0 && rc != DB_KEYEXIST ) {			err = "c_put id";			goto fail;		}	} else {		/* initial c_get failed, nothing was done */fail:		Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: "			"%s failed: %s (%d)\n", err, db_strerror(rc), rc );		cursor->c_close( cursor );		return rc;	}	rc = cursor->c_close( cursor );	if( rc != 0 ) {		Debug( LDAP_DEBUG_ANY, "=> bdb_idl_insert_key: "			"c_close failed: %s (%d)\n",			db_strerror(rc), rc, 0 );	}	return rc;}intbdb_idl_delete_key(	BackendDB	*be,	DB			*db,	DB_TXN		*tid,	DBT			*key,	ID			id ){	struct bdb_info *bdb = (struct bdb_info *) be->be_private;	int	rc;	DBT data;	DBC *cursor;	ID lo, hi, tmp, nid, nlo, nhi;	char *err;	{		char buf[16];		Debug( LDAP_DEBUG_ARGS,			"bdb_idl_delete_key: %lx %s\n", 			(long) id, bdb_show_key( key, buf ), 0 );	}	assert( id != NOID );	if ( bdb->bi_idl_cache_max_size ) {		bdb_idl_cache_del( bdb, db, key );	}	BDB_ID2DISK( id, &nid );	DBTzero( &data );	data.data = &tmp;	data.size = sizeof( id );	data.ulen = data.size;	data.flags = DB_DBT_USERMEM;	rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );	if ( rc != 0 ) {		Debug( LDAP_DEBUG_ANY, "=> bdb_idl_delete_key: "			"cursor failed: %s (%d)\n", db_strerror(rc), rc, 0 );		return rc;	}	/* Fetch the first data item for this key, to see if it	 * exists and if it's a range.	 */	rc = cursor->c_get( cursor, key, &data, DB_SET );	err = "c_get";	if ( rc == 0 ) {		if ( tmp != 0 ) {			/* Not a range, just delete it */			if (tmp != nid) {				/* position to correct item */				tmp = nid;				rc = cursor->c_get( cursor, key, &data, DB_GET_BOTH );				if ( rc != 0 ) {					err = "c_get id";					goto fail;				}			}			rc = cursor->c_del( cursor, 0 );			if ( rc != 0 ) {				err = "c_del id";				goto fail;			}		} else {			/* It's a range, see if we need to rewrite			 * the boundaries			 */			data.data = &nlo;			rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );			if ( rc != 0 ) {				err = "c_get lo";				goto fail;			}			BDB_DISK2ID( &nlo, &lo );			data.data = &nhi;			rc = cursor->c_get( cursor, key, &data, DB_NEXT_DUP );			if ( rc != 0 ) {				err = "c_get hi";				goto fail;			}			BDB_DISK2ID( &nhi, &hi );			if ( id == lo || id == hi ) {				if ( id == lo ) {					id++;					lo = id;				} else if ( id == hi ) {					id--;					hi = id;				}				if ( lo >= hi ) {				/* The range has collapsed... */					rc = db->del( db, tid, key, 0 );					if ( rc != 0 ) {						err = "del";						goto fail;					}				} else {					if ( id == lo ) {						/* reposition on lo slot */						data.data = &nlo;						cursor->c_get( cursor, key, &data, DB_PREV );					}					rc = cursor->c_del( cursor, 0 );					if ( rc != 0 ) {						err = "c_del";						goto fail;					}				}				if ( lo <= hi ) {					BDB_ID2DISK( id, &nid );					data.data = &nid;					rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );					if ( rc != 0 ) {						err = "c_put lo/hi";						goto fail;					}				}			}		}	} else {		/* initial c_get failed, nothing was done */fail:		if ( rc != DB_NOTFOUND ) {		Debug( LDAP_DEBUG_ANY, "=> bdb_idl_delete_key: "			"%s failed: %s (%d)\n", err, db_strerror(rc), rc );		}		cursor->c_close( cursor );		return rc;	}	rc = cursor->c_close( cursor );	if( rc != 0 ) {		Debug( LDAP_DEBUG_ANY,			"=> bdb_idl_delete_key: c_close failed: %s (%d)\n",			db_strerror(rc), rc, 0 );	}	return rc;}/* * idl_intersection - return a = a intersection b */intbdb_idl_intersection(	ID *a,	ID *b ){	ID ida, idb;	ID idmax, idmin;	ID cursora = 0, cursorb = 0, cursorc;	int swap = 0;	if ( BDB_IDL_IS_ZERO( a ) || BDB_IDL_IS_ZERO( b ) ) {		a[0] = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -