#include #include #include #include #include #define MAX_LINE_LENGTH 1024 #define NUM_THREADS 16 // Define the struct to hold the parsed data for each line typedef struct { char *titleId; int ordering; char *title; char *region; char *language; char *types; char *attributes; int isOriginalTitle; } TitleLanguages; typedef struct { char *filename; long start_offset; long end_offset; TitleLanguages *parsed_lines; int *line_count; } ThreadData; char *strdup(const char *s) { size_t len = strlen(s) + 1; char *dup = malloc(len); if (dup) { memcpy(dup, s, len); } return dup; } // Function to process the file chunk for each thread void* processAkaLinesThread(void *arg) { ThreadData *data = (ThreadData*)arg; FILE *file = fopen(data->filename, "r"); if (!file) { perror("Error opening file in thread"); pthread_exit(NULL); } char line[MAX_LINE_LENGTH]; long start = data->start_offset; long end = data->end_offset; int line_count = 0; printf("Thread starting: processing from %ld to %ld\n", start, end); fseek(file, start, SEEK_SET); // Read and process lines within the given range while (ftell(file) < end && fgets(line, sizeof(line), file)) { line[strcspn(line, "\n")] = 0; char *titleId = strtok(line, "\t"); if (!titleId) continue; char *ordering_str = strtok(NULL, "\t"); char *title = strtok(NULL, "\t"); char *region = strtok(NULL, "\t"); char *language = strtok(NULL, "\t"); char *types = strtok(NULL, "\t"); char *attributes = strtok(NULL, "\t"); char *isOriginalTitle_str = strtok(NULL, "\t"); if (!ordering_str || !title || !region || !language || !types || !attributes || !isOriginalTitle_str) { continue; } TitleLanguages *current_line = &data->parsed_lines[line_count]; current_line->titleId = strdup(titleId); current_line->ordering = atoi(ordering_str); current_line->title = strdup(title); current_line->region = strdup(region); current_line->language = strdup(language); current_line->types = strdup(types); current_line->attributes = strdup(attributes); current_line->isOriginalTitle = atoi(isOriginalTitle_str); if (!current_line->titleId || !current_line->title || !current_line->region || !current_line->language || !current_line->types || !current_line->attributes) { perror("Memory allocation failed"); fclose(file); pthread_exit(NULL); } line_count++; } *(data->line_count) = line_count; fclose(file); pthread_exit(NULL); } // Function to read the Akas file and process lines with multiple threads int readAkasWithThreads(const char *filename, TitleLanguages **languages) { FILE *fh = fopen(filename, "r"); if (!fh) { perror("Error opening file"); return -1; } fseek(fh, 0, SEEK_END); long file_size = ftell(fh); fseek(fh, 0, SEEK_SET); printf("File size: %ld bytes\n", file_size); int num_lines = file_size / MAX_LINE_LENGTH * NUM_THREADS; *languages = malloc(num_lines * sizeof(TitleLanguages)); if (!*languages) { perror("Memory allocation failed"); fclose(fh); return -1; } pthread_t threads[NUM_THREADS]; ThreadData thread_data[NUM_THREADS]; int line_counts[NUM_THREADS]; long chunk_size = file_size / NUM_THREADS; for (int i = 0; i < NUM_THREADS; i++) { thread_data[i].filename = (char *)filename; thread_data[i].start_offset = i * chunk_size; thread_data[i].end_offset = (i == NUM_THREADS - 1) ? file_size : (i + 1) * chunk_size; thread_data[i].parsed_lines = *languages + (i * num_lines / NUM_THREADS); thread_data[i].line_count = &line_counts[i]; printf("Thread %d: start offset %ld, end offset %ld\n", i, thread_data[i].start_offset, thread_data[i].end_offset); pthread_create(&threads[i], NULL, processAkaLinesThread, &thread_data[i]); } for (int i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } fclose(fh); int total_lines = 0; for (int i = 0; i < NUM_THREADS; i++) { total_lines += line_counts[i]; } return total_lines; } int testLanguages(void) { TitleLanguages *languages = NULL; int line_count = 0; line_count = readAkasWithThreads("imdb/title.akas.tsv", &languages); printf("Processed %d lines\n", line_count); printf("First and last 4 lines processed:\n"); for (int i = 0; i < line_count; i++) { if (i < 4) { printf("Line %d: %s, %d, %s, %s, %s, %s, %d\n", i + 1, languages[i].titleId, languages[i].ordering, languages[i].title, languages[i].region, languages[i].language, languages[i].types, languages[i].isOriginalTitle); } if (i >= line_count - 4) { printf("Line %d: %s, %d, %s, %s, %s, %s, %d\n", i + 1, languages[i].titleId, languages[i].ordering, languages[i].title, languages[i].region, languages[i].language, languages[i].types, languages[i].isOriginalTitle); } } for (int i = 0; i < line_count; i++) { free(languages[i].titleId); free(languages[i].title); free(languages[i].region); free(languages[i].language); free(languages[i].types); free(languages[i].attributes); } free(languages); return 0; }