dvd files
wget https://git.christianimmanuel.de/games/dvd/archive/dvd.tar.gzimdb_aka.c raw
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#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;
}