/* Bins.c Possible bin array for RadixSort */ #include #include #include #include "Bins.h" struct t_bins { int n_bins, max_items; int *bin_cnt; TYPE **bin_pts; }; /* Construct an array of n_bins bins, each with items_per_bin spaces */ Bins ConsBins( int n_bins, int items_per_bin ) { Bins b; int i; #ifdef ONE_LARGE int max; TYPE *bins; #endif /* fprintf(stdout, "ConsBins %d/%d ", n_bins, items_per_bin ); fflush( stdout ); */ b = (Bins)malloc( sizeof( struct t_bins ) ); if ( b != NULL ) { b->n_bins = n_bins; b->max_items = items_per_bin; b->bin_pts = (TYPE **)malloc( n_bins*sizeof(TYPE *) ); b->bin_cnt = (int *)calloc( n_bins, sizeof(int) ); if ( b->bin_pts != NULL ) { #ifdef ONE_LARGE /* Allocate a single large bin */ max = n_bins*items_per_bin*sizeof(TYPE); bins = malloc( max ); if( bins == NULL ) { printf("ConsBins: insuff mem %d bytes needed\n", max ); return NULL; } /* Divide it into n_bins, each holding items_per_bin items */ for(i=0;ibin_pts[i] = bins; bins += (items_per_bin); } #else /* Allocate n_bins individual bins */ for(i=0;ibin_pts[i] = (TYPE *)malloc( items_per_bin*sizeof(TYPE) ); if( b->bin_pts[i] == NULL ) { printf("ConsBins: insuff mem after %d bins\n", i ); b = NULL; break; } } #endif } } else { fprintf( stdout, "Insuff mem\n"); } return b; } int AddItem( Bins b, TYPE item, int bin_index ) { /* Add item to bin bin_index Pre: b != NULL && item != NULL && bin_index >= 0 && bin_index < n_bins */ int k; assert( b != NULL ); assert( bin_index >= 0 ); assert( bin_index < b->n_bins ); k = b->bin_cnt[bin_index]; assert( (k>=0) && (kmax_items) ); assert( (b->bin_pts[bin_index]) != NULL ); (b->bin_pts[bin_index])[k] = item; b->bin_cnt[bin_index]++; return 1; } TYPE *MergeBins( Bins b, TYPE *list ) { /* Merge the bins by copying all the elements in bins 1..n_bins-1 into list return a pointer to list (This pointer can be used in the next phase!) */ int j, k; TYPE *lp; assert( b != NULL ); assert( list != NULL ); lp = list; for( j = 0; jn_bins; j++ ) { for(k=0;kbin_cnt[j];k++) { *lp++ = (b->bin_pts[j])[k]; } } return list; } void FreeUnusedBins( Bins b ) { /* Free bins 1 .. n_bins-1 in preparation for next phase */ int k; assert( b != NULL ); #ifdef ONE_LARGE free( b->bin_pts[0] ); #else for(k=0;kn_bins;k++) { assert( b->bin_pts[k] != NULL ); free( b->bin_pts[k] ); } #endif free( b->bin_pts ); } void DeleteBins( Bins b ) { /* Destructor .. frees all space used by b */ assert( b != NULL ); FreeUnusedBins( b ); free( b->bin_cnt ); free( b ); }