/*TITLE mailing list program*/ /****keyword-flag*** "%v %f %n" */ /* "12 21-Mar-98,19:23:00 MAILX.CPP" */ #include #include #include #include "mailx.h" #include "bitfunc.h" #include "date.h" #include "..\\common\\timings.h" CustomerSelection initialize(char *min,char *max,char *start,char *end); void process(FILE *customer_data_file, FILE *customer_list_file, CustomerSelection customer_selection); void terminate(FILE *customer_data_file, FILE *customer_list_file); static int override; int main(int argc, char *argv[]) { start_timing(); FILE *customer_data_file; FILE *customer_list_file; char customer_data_file_name[100]; char customer_list_file_name[100]; CustomerSelection customer_selection; if (argc < 6) { printf("Usage: mailx customer_file min max start end [override]\n"); exit(1); } if (argc < 7) override = 0; else override = atoi(argv[6]); strcpy(customer_data_file_name,argv[1]); strcat(customer_data_file_name,".dat"); strcpy(customer_list_file_name,argv[1]); strcat(customer_list_file_name,".lst"); customer_data_file = fopen(customer_data_file_name,"rb"); if (customer_data_file == NULL) { printf("Cannot open file %s.\n",customer_data_file_name); exit(1); } customer_list_file = fopen(customer_list_file_name,"w"); if (customer_list_file == NULL) { printf("Cannot open file %s.\n",customer_list_file_name); exit(1); } setvbuf(customer_list_file, NULL, _IOFBF, 32000); customer_selection = initialize(argv[2],argv[3],argv[4],argv[5]); process(customer_data_file, customer_list_file, customer_selection); terminate(customer_data_file, customer_list_file); end_timing(); return 0; } CustomerSelection initialize(char *min,char *max,char *start,char *end) { CustomerSelection temp_selection; temp_selection.min_spent = atoi(min); temp_selection.max_spent = atoi(max); temp_selection.min_date = date_string_to_days(start); temp_selection.max_date = date_string_to_days(end); return(temp_selection); } void process(FILE *customer_data_file, FILE *customer_list_file, CustomerSelection customer_selection) { int i; unsigned k; unsigned zip_block_start; unsigned zip_count; unsigned zip_entry; unsigned list_index; unsigned items_read; unsigned items_processed; int total_items_read; DataRecord search_record[BATCH_SIZE]; DataRecord data_record; long data_file_length; long data_file_count; char *found; ZipRecord *temp_zip_pointer[ZIP_BLOCK_ENTRIES]; ZipRecord **zip_pointer; ZipRecord *zip_block[ZIP_BLOCK_COUNT]; unsigned *record_number; unsigned items_found; char *file_buffer; unsigned processing_batch = BATCH_SIZE; int current_zip_block = -1; int current_zip_entry = ZIP_BLOCK_ENTRIES; int countdown; setvbuf(customer_data_file, file_buffer, _IOFBF, 32000); fseek(customer_data_file, 0L, SEEK_END); data_file_length = ftell(customer_data_file); fseek(customer_data_file, 0L, SEEK_SET); data_file_count = data_file_length / sizeof(DataRecord); fseek(customer_data_file, 0L, SEEK_SET); file_buffer = (char *)calloc(32000,1); found = (char *)allocate_bitmap(data_file_count); items_found = 0; total_items_read = 0; countdown = override; for (;;) { items_read = fread(search_record, sizeof(DataRecord), processing_batch, customer_data_file); for (items_processed = 0; items_processed < items_read; items_processed ++) { if (override == 0) { if (search_record[items_processed].dollars_spent < customer_selection.min_spent) continue; if (search_record[items_processed].dollars_spent > customer_selection.max_spent) continue; if (search_record[items_processed].date_last_here < customer_selection.min_date) continue; if (search_record[items_processed].date_last_here > customer_selection.max_date) continue; } else { countdown --; if (countdown > 0) continue; countdown = override; } items_found ++; setbit(found,(long)(items_processed+total_items_read)); if (current_zip_entry == ZIP_BLOCK_ENTRIES) { current_zip_block ++; current_zip_entry = 0; zip_block[current_zip_block] = (ZipRecord *) calloc(ZIP_BLOCK_ENTRIES,sizeof(ZipRecord)); for (k = 0; k < ZIP_BLOCK_ENTRIES; k ++) temp_zip_pointer[k] = zip_block[current_zip_block] + k; } memcpy(&temp_zip_pointer[current_zip_entry]->zip, search_record[items_processed].zip,ZIP_LENGTH+1); temp_zip_pointer[current_zip_entry]->record_number = items_processed+total_items_read; current_zip_entry ++; } total_items_read += items_read; if (items_read != processing_batch) break; } timing("Pass 1 time"); zip_pointer = (ZipRecord **)calloc(items_found,sizeof(ZipRecord *)); zip_block_start = 0; for (i = 0; i <= current_zip_block; i ++) { if (i < current_zip_block) zip_count = ZIP_BLOCK_ENTRIES; else zip_count = items_found-zip_block_start; for (zip_entry = 0; zip_entry < zip_count; zip_entry ++) { zip_pointer[zip_block_start+zip_entry] = zip_block[i] + zip_entry; } zip_block_start += zip_entry; } record_number = (unsigned *)calloc(items_found,sizeof(int)); list_index = 0; for (i = 0; i < total_items_read; i ++) { if (testbit(found,i)) { record_number[list_index] = i; list_index ++; } } Megasort((unsigned char **)zip_pointer, record_number, ZIP_LENGTH, items_found); timing("Sorting time"); setvbuf(customer_data_file, file_buffer, _IOFBF, sizeof(DataRecord)); for (items_processed = 0; items_processed < items_found; items_processed ++) { fseek(customer_data_file, (long)(zip_pointer[items_processed]->record_number)*(long)sizeof(DataRecord),SEEK_SET); fread(&data_record, sizeof(DataRecord), 1, customer_data_file); fprintf(customer_list_file,"%s %s %s\n",data_record.first_name, data_record.last_name,zip_pointer[items_processed]->zip); } timing("Pass 2 time"); printf("Total records selected: %ld\n",items_found); free(file_buffer); free(found); free(zip_pointer); for (i = 0; i <= current_zip_block; i ++) free(zip_block[i]); } void terminate(FILE *customer_data_file, FILE *customer_list_file) { fclose(customer_data_file); fclose(customer_list_file); }