FreeBSD/sys/netpfil/ipfw/dn_heap.c
/*
 * Initialize, allocating bucket pointers inline.
 * Recycle previous record if possible.
 * If the 'newh' function is not supplied, we assume that the
 * key passed to ht_find is the same object to be stored in.
 */
Initialize, allocating bucket pointers inline.
Recycle previous record if possible.
If the 'newh' function is not supplied, we assume that the
key passed to ht_find is the same object to be stored in.
Initialize allocating bucket pointers inline . Recycle previous record if possible . If the ' newh ' function is not supplied we assume that the key passed to ht_find is the same object to be stored in .
struct dn_ht *
dn_ht_init(struct dn_ht *ht, int buckets, int ofs,
        uint32_t (*h)(uintptr_t, int, void *),
        int (*match)(void *, uintptr_t, int, void *),
	void *(*newh)(uintptr_t, int, void *))
{
	int l;
	int b_min; 
	int b_max; 
	int b_ori; 
	if (h == NULL || match == NULL) {
		printf("--- missing hash or match function");
		return NULL;
	}
	if (buckets < 1 || buckets > 65536)
		return NULL;
	b_ori = buckets;
	buckets |= buckets >> 1;
	buckets |= buckets >> 2;
	buckets |= buckets >> 4;
	buckets |= buckets >> 8;
	buckets |= buckets >> 16;
	b_max = buckets; 
	b_min = buckets >> 1; 
	if (b_min * 4000 / 3000 < b_ori)
		buckets = b_max;
	else
		buckets = b_min;
	if (ht) {	
		if (buckets <= ht->buckets) {
			ht->buckets = buckets;
		} else {
			if (ht->ht != (void *)(ht + 1))
				free(ht->ht, M_DN_HEAP);
			free(ht, M_DN_HEAP);
			ht = NULL;
		}
	}
	if (ht == NULL) {
		l = sizeof(*ht) + (buckets + 1) * sizeof(void **);
		ht = malloc(l, M_DN_HEAP, M_NOWAIT | M_ZERO);
	}
	if (ht) {
		ht->ht = (void **)(ht + 1);
		ht->buckets = buckets;
		ht->ofs = ofs;
		ht->hash = h;
		ht->match = match;
		ht->newh = newh;
	}
	return ht;
}
struct dn_ht * dn_ht_init ( struct dn_ht * ht , int buckets , int ofs , uint32_t ( * h ) ( uintptr_t , int , void * ) , int ( * match ) ( void * , uintptr_t , int , void * ) , void * ( * newh ) ( uintptr_t , int , void * ) ) { int l ; int b_min ; int b_max ; int b_ori ; if ( h == NULL || match == NULL ) { printf ( " " ) ; return NULL ; } if ( buckets < 1 || buckets > 65536 ) return NULL ; b_ori = buckets ; buckets |= buckets >> 1 ; buckets |= buckets >> 2 ; buckets |= buckets >> 4 ; buckets |= buckets >> 8 ; buckets |= buckets >> 16 ; b_max = buckets ; b_min = buckets >> 1 ; if ( b_min * 4000 / 3000 < b_ori ) buckets = b_max ; else buckets = b_min ; if ( ht ) { if ( buckets <= ht -> buckets ) { ht -> buckets = buckets ; } else { if ( ht -> ht != ( void * ) ( ht + 1 ) ) free ( ht -> ht , M_DN_HEAP ) ; free ( ht , M_DN_HEAP ) ; ht = NULL ; } } if ( ht == NULL ) { l = sizeof ( * ht ) + ( buckets + 1 ) * sizeof ( void * * ) ; ht = malloc ( l , M_DN_HEAP , M_NOWAIT | M_ZERO ) ; } if ( ht ) { ht -> ht = ( void * * ) ( ht + 1 ) ; ht -> buckets = buckets ; ht -> ofs = ofs ; ht -> hash = h ; ht -> match = match ; ht -> newh = newh ; } return ht ; }
Initialize, allocating bucket pointers inline.
Initialize allocating bucket pointers inline .
/*
	 * Notes about rounding bucket size to a power of two.
	 * Given the original bucket size, we compute the nearest lower and
	 * higher power of two, minus 1  (respectively b_min and b_max) because
	 * this value will be used to do an AND with the index returned
	 * by hash function.
	 * To choice between these two values, the original bucket size is
	 * compared with b_min. If the original size is greater than 4/3 b_min,
	 * we round the bucket size to b_max, else to b_min.
	 * This ratio try to round to the nearest power of two, advantaging
	 * the greater size if the different between two power is relatively
	 * big.
	 * Rounding the bucket size to a power of two avoid the use of
	 * module when calculating the correct bucket.
	 * The ht->buckets variable store the bucket size - 1 to simply
	 * do an AND between the index returned by hash function and ht->bucket
	 * instead of a module.
	 */ /* min buckets */ /* max buckets */ /* original buckets */ /* calculate next power of 2, - 1*/ /* Next power */ /* Previous power */ /* Calculate the 'nearest' bucket size */ /* see if we can reuse */ /* free pointers if not allocated inline */ /* Allocate buckets + 1 entries because buckets is use to
		 * do the AND with the index returned by hash function
		 */