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

📄 idl.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		return 0;	}	idmin = IDL_MAX( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) );	idmax = IDL_MIN( BDB_IDL_LAST(a), BDB_IDL_LAST(b) );	if ( idmin > idmax ) {		a[0] = 0;		return 0;	} else if ( idmin == idmax ) {		a[0] = 1;		a[1] = idmin;		return 0;	}	if ( BDB_IDL_IS_RANGE( a ) ) {		if ( BDB_IDL_IS_RANGE(b) ) {		/* If both are ranges, just shrink the boundaries */			a[1] = idmin;			a[2] = idmax;			return 0;		} else {		/* Else swap so that b is the range, a is a list */			ID *tmp = a;			a = b;			b = tmp;			swap = 1;		}	}	/* If a range completely covers the list, the result is	 * just the list. If idmin to idmax is contiguous, just	 * turn it into a range.	 */	if ( BDB_IDL_IS_RANGE( b )		&& BDB_IDL_FIRST( b ) <= BDB_IDL_FIRST( a )		&& BDB_IDL_LAST( b ) >= BDB_IDL_LAST( a ) ) {		if (idmax - idmin + 1 == a[0])		{			a[0] = NOID;			a[1] = idmin;			a[2] = idmax;		}		goto done;	}	/* Fine, do the intersection one element at a time.	 * First advance to idmin in both IDLs.	 */	cursora = cursorb = idmin;	ida = bdb_idl_first( a, &cursora );	idb = bdb_idl_first( b, &cursorb );	cursorc = 0;	while( ida <= idmax || idb <= idmax ) {		if( ida == idb ) {			a[++cursorc] = ida;			ida = bdb_idl_next( a, &cursora );			idb = bdb_idl_next( b, &cursorb );		} else if ( ida < idb ) {			ida = bdb_idl_next( a, &cursora );		} else {			idb = bdb_idl_next( b, &cursorb );		}	}	a[0] = cursorc;done:	if (swap)		BDB_IDL_CPY( b, a );	return 0;}/* * idl_union - return a = a union b */intbdb_idl_union(	ID	*a,	ID	*b ){	ID ida, idb;	ID cursora = 0, cursorb = 0, cursorc;	if ( BDB_IDL_IS_ZERO( b ) ) {		return 0;	}	if ( BDB_IDL_IS_ZERO( a ) ) {		BDB_IDL_CPY( a, b );		return 0;	}	if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ) {over:		ida = IDL_MIN( BDB_IDL_FIRST(a), BDB_IDL_FIRST(b) );		idb = IDL_MAX( BDB_IDL_LAST(a), BDB_IDL_LAST(b) );		a[0] = NOID;		a[1] = ida;		a[2] = idb;		return 0;	}	ida = bdb_idl_first( a, &cursora );	idb = bdb_idl_first( b, &cursorb );	cursorc = b[0];	/* The distinct elements of a are cat'd to b */	while( ida != NOID || idb != NOID ) {		if ( ida < idb ) {			if( ++cursorc > BDB_IDL_UM_MAX ) {				goto over;			}			b[cursorc] = ida;			ida = bdb_idl_next( a, &cursora );		} else {			if ( ida == idb )				ida = bdb_idl_next( a, &cursora );			idb = bdb_idl_next( b, &cursorb );		}	}	/* b is copied back to a in sorted order */	a[0] = cursorc;	cursora = 1;	cursorb = 1;	cursorc = b[0]+1;	while (cursorb <= b[0] || cursorc <= a[0]) {		if (cursorc > a[0])			idb = NOID;		else			idb = b[cursorc];		if (cursorb <= b[0] && b[cursorb] < idb)			a[cursora++] = b[cursorb++];		else {			a[cursora++] = idb;			cursorc++;		}	}	return 0;}#if 0/* * bdb_idl_notin - return a intersection ~b (or a minus b) */intbdb_idl_notin(	ID	*a,	ID	*b,	ID *ids ){	ID ida, idb;	ID cursora = 0, cursorb = 0;	if( BDB_IDL_IS_ZERO( a ) ||		BDB_IDL_IS_ZERO( b ) ||		BDB_IDL_IS_RANGE( b ) )	{		BDB_IDL_CPY( ids, a );		return 0;	}	if( BDB_IDL_IS_RANGE( a ) ) {		BDB_IDL_CPY( ids, a );		return 0;	}	ida = bdb_idl_first( a, &cursora ),	idb = bdb_idl_first( b, &cursorb );	ids[0] = 0;	while( ida != NOID ) {		if ( idb == NOID ) {			/* we could shortcut this */			ids[++ids[0]] = ida;			ida = bdb_idl_next( a, &cursora );		} else if ( ida < idb ) {			ids[++ids[0]] = ida;			ida = bdb_idl_next( a, &cursora );		} else if ( ida > idb ) {			idb = bdb_idl_next( b, &cursorb );		} else {			ida = bdb_idl_next( a, &cursora );			idb = bdb_idl_next( b, &cursorb );		}	}	return 0;}#endifID bdb_idl_first( ID *ids, ID *cursor ){	ID pos;	if ( ids[0] == 0 ) {		*cursor = NOID;		return NOID;	}	if ( BDB_IDL_IS_RANGE( ids ) ) {		if( *cursor < ids[1] ) {			*cursor = ids[1];		}		return *cursor;	}	if ( *cursor == 0 )		pos = 1;	else		pos = bdb_idl_search( ids, *cursor );	if( pos > ids[0] ) {		return NOID;	}	*cursor = pos;	return ids[pos];}ID bdb_idl_next( ID *ids, ID *cursor ){	if ( BDB_IDL_IS_RANGE( ids ) ) {		if( ids[2] < ++(*cursor) ) {			return NOID;		}		return *cursor;	}	if ( ++(*cursor) <= ids[0] ) {		return ids[*cursor];	}	return NOID;}#ifdef BDB_HIER/* Add one ID to an unsorted list. We ensure that the first element is the * minimum and the last element is the maximum, for fast range compaction. *   this means IDLs up to length 3 are always sorted... */int bdb_idl_append_one( ID *ids, ID id ){	if (BDB_IDL_IS_RANGE( ids )) {		/* if already in range, treat as a dup */		if (id >= BDB_IDL_FIRST(ids) && id <= BDB_IDL_LAST(ids))			return -1;		if (id < BDB_IDL_FIRST(ids))			ids[1] = id;		else if (id > BDB_IDL_LAST(ids))			ids[2] = id;		return 0;	}	if ( ids[0] ) {		ID tmp;		if (id < ids[1]) {			tmp = ids[1];			ids[1] = id;			id = tmp;		}		if ( ids[0] > 1 && id < ids[ids[0]] ) {			tmp = ids[ids[0]];			ids[ids[0]] = id;			id = tmp;		}	}	ids[0]++;	if ( ids[0] >= BDB_IDL_UM_MAX ) {		ids[0] = NOID;		ids[2] = id;	} else {		ids[ids[0]] = id;	}	return 0;}/* Append sorted list b to sorted list a. The result is unsorted but * a[1] is the min of the result and a[a[0]] is the max. */int bdb_idl_append( ID *a, ID *b ){	ID ida, idb, tmp, swap = 0;	if ( BDB_IDL_IS_ZERO( b ) ) {		return 0;	}	if ( BDB_IDL_IS_ZERO( a ) ) {		BDB_IDL_CPY( a, b );		return 0;	}	ida = BDB_IDL_LAST( a );	idb = BDB_IDL_LAST( b );	if ( BDB_IDL_IS_RANGE( a ) || BDB_IDL_IS_RANGE(b) ||		a[0] + b[0] >= BDB_IDL_UM_MAX ) {		a[2] = IDL_MAX( ida, idb );		a[1] = IDL_MIN( a[1], b[1] );		a[0] = NOID;		return 0;	}	if ( b[0] > 1 && ida > idb ) {		swap = idb;		a[a[0]] = idb;		b[b[0]] = ida;	}	if ( b[1] < a[1] ) {		tmp = a[1];		a[1] = b[1];	} else {		tmp = b[1];	}	a[0]++;	a[a[0]] = tmp;	if ( b[0] > 1 ) {		int i = b[0] - 1;		AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID));		a[0] += i;	}	if ( swap ) {		b[b[0]] = swap;	}	return 0;}#if 1/* Quicksort + Insertion sort for small arrays */#define SMALL	8#define	SWAP(a,b)	itmp=(a);(a)=(b);(b)=itmpvoidbdb_idl_sort( ID *ids, ID *tmp ){	int *istack = (int *)tmp;	int i,j,k,l,ir,jstack;	ID a, itmp;	if ( BDB_IDL_IS_RANGE( ids ))		return;	ir = ids[0];	l = 1;	jstack = 0;	for(;;) {		if (ir - l < SMALL) {	/* Insertion sort */			for (j=l+1;j<=ir;j++) {				a = ids[j];				for (i=j-1;i>=1;i--) {					if (ids[i] <= a) break;					ids[i+1] = ids[i];				}				ids[i+1] = a;			}			if (jstack == 0) break;			ir = istack[jstack--];			l = istack[jstack--];		} else {			k = (l + ir) >> 1;	/* Choose median of left, center, right */			SWAP(ids[k], ids[l+1]);			if (ids[l] > ids[ir]) {				SWAP(ids[l], ids[ir]);			}			if (ids[l+1] > ids[ir]) {				SWAP(ids[l+1], ids[ir]);			}			if (ids[l] > ids[l+1]) {				SWAP(ids[l], ids[l+1]);			}			i = l+1;			j = ir;			a = ids[l+1];			for(;;) {				do i++; while(ids[i] < a);				do j--; while(ids[j] > a);				if (j < i) break;				SWAP(ids[i],ids[j]);			}			ids[l+1] = ids[j];			ids[j] = a;			jstack += 2;			if (ir-i+1 >= j-1) {				istack[jstack] = ir;				istack[jstack-1] = i;				ir = j-1;			} else {				istack[jstack] = j-1;				istack[jstack-1] = l;				l = i;			}		}	}}#else/* 8 bit Radix sort + insertion sort *  * based on code from http://www.cubic.org/docs/radix.htm * with improvements by mbackes@symas.com and hyc@symas.com * * This code is O(n) but has a relatively high constant factor. For lists * up to ~50 Quicksort is slightly faster; up to ~100 they are even. * Much faster than quicksort for lists longer than ~100. Insertion * sort is actually superior for lists <50. */#define BUCKETS	(1<<8)#define SMALL	50voidbdb_idl_sort( ID *ids, ID *tmp ){	int count, soft_limit, phase = 0, size = ids[0];	ID *idls[2];	unsigned char *maxv = (unsigned char *)&ids[size]; 	if ( BDB_IDL_IS_RANGE( ids )) 		return;	/* Use insertion sort for small lists */	if ( size <= SMALL ) {		int i,j;		ID a;		for (j=1;j<=size;j++) {			a = ids[j];			for (i=j-1;i>=1;i--) {				if (ids[i] <= a) break;				ids[i+1] = ids[i];			}			ids[i+1] = a;		}		return;	}	tmp[0] = size;	idls[0] = ids;	idls[1] = tmp;#if BYTE_ORDER == BIG_ENDIAN    for (soft_limit = 0; !maxv[soft_limit]; soft_limit++);#else    for (soft_limit = sizeof(ID)-1; !maxv[soft_limit]; soft_limit--);#endif	for (#if BYTE_ORDER == BIG_ENDIAN	count = sizeof(ID)-1; count >= soft_limit; --count#else	count = 0; count <= soft_limit; ++count#endif	) {		unsigned int num[BUCKETS], * np, n, sum;		int i;        ID *sp, *source, *dest;        unsigned char *bp, *source_start;		source = idls[phase]+1;		dest = idls[phase^1]+1;		source_start =  ((unsigned char *) source) + count;        np = num;        for ( i = BUCKETS; i > 0; --i ) *np++ = 0;		/* count occurences of every byte value */		bp = source_start;        for ( i = size; i > 0; --i, bp += sizeof(ID) )				num[*bp]++;		/* transform count into index by summing elements and storing		 * into same array		 */        sum = 0;        np = num;        for ( i = BUCKETS; i > 0; --i ) {                n = *np;                *np++ = sum;                sum += n;        }		/* fill dest with the right values in the right place */		bp = source_start;        sp = source;        for ( i = size; i > 0; --i, bp += sizeof(ID) ) {                np = num + *bp;                dest[*np] = *sp++;                ++(*np);        }		phase ^= 1;	}	/* copy back from temp if needed */	if ( phase ) {		ids++; tmp++;		for ( count = 0; count < size; ++count ) 			*ids++ = *tmp++;	}}#endif	/* Quick vs Radix */#endif	/* BDB_HIER */

⌨️ 快捷键说明

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