CoolFace
Datasetpublic

Yehor/FineWebUA-links-p1-500m

Intro This dataset contains links to Ukrainian websites and sitemaps derived from the Common Crawl corpus. A part of the Fineweb-UA project. Stats 42263126 part-00000.sitemap-links.tsv 45051846 part-00001.sitemap-links.tsv 26360778 part-00002.sitemap-links.tsv 49879673 part-00003.sitemap-links.tsv 29744936 part-00004.sitemap-links.tsv 61139341 part-00005.sitemap-links.tsv 43183739 part-00006.sitemap-links.tsv 53279243 part-00007.sitemap-links.tsv 60319695… See the full description on the dataset page: https://huggingface.co/datasets/Yehor/FineWebUA-links-p1-500m.

sourceHugging Faceapache-2.0updated 3mo agoView on Hugging Face
0likes63downloads
Dataset Card

Intro

This dataset contains links to Ukrainian websites and sitemaps derived from the Common Crawl corpus. A part of the Fineweb-UA project.

Stats

  • —42263126 part-00000.sitemap-links.tsv
  • —45051846 part-00001.sitemap-links.tsv
  • —26360778 part-00002.sitemap-links.tsv
  • —49879673 part-00003.sitemap-links.tsv
  • —29744936 part-00004.sitemap-links.tsv
  • —61139341 part-00005.sitemap-links.tsv
  • —43183739 part-00006.sitemap-links.tsv
  • —53279243 part-00007.sitemap-links.tsv
  • —60319695 part-00008.sitemap-links.tsv
  • —38988670 part-00009.sitemap-links.tsv

Total: 500 090 720 links (500+ million)

Domains

  • —Total Unique Domains: 4511
  • —Total Unique Sitemaps: 62290

Counter

c
// gcc -O3 -pthread fast_counter.c -o fast_counter

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#define HASH_SIZE 30000023  // Bumped higher for 7GB files to avoid collisions
#define MAX_LINE 8192

typedef struct Node {
    char *str;
    struct Node *next;
} Node;

typedef struct {
    char *filename;
    Node **domains_hash;
    Node **sitemaps_hash;
    long long unique_domains;
    long long unique_sitemaps;
} ThreadData;

// DJB2 Hash Function
unsigned long hash(const char *str) {
    unsigned long hash = 5381;
    int c;
    while ((c = (unsigned char)*str++)) {
        hash = ((hash << 5) + hash) + c;
    }
    return hash % HASH_SIZE;
}

// Thread-safe isolation insertion
int insert(Node **table, const char *str) {
    unsigned long h = hash(str);
    Node *curr = table[h];
    while (curr != NULL) {
        if (strcmp(curr->str, str) == 0) {
            return 0;
        }
        curr = curr->next;
    }
    Node *new_node = malloc(sizeof(Node));
    if (!new_node) {
        perror("Allocation failed");
        exit(EXIT_FAILURE);
    }
    new_node->str = strdup(str);
    new_node->next = table[h];
    table[h] = new_node;
    return 1;
}

// Fixed: Safely extracts domain and returns 1 on success, 0 on failure
int extract_domain(const char *url, char *domain) {
    if (strncmp(url, "http://", 7) == 0) {
        url += 7;
    } else if (strncmp(url, "https://", 8) == 0) {
        url += 8;
    } else {
        return 0;
    }
    char *start = domain;
    while (*url && *url != '/' && *url != ':' && *url != '\t' && *url != ' ' && *url != '\n' && *url != '\r') {
        *domain++ = *url++;
    }
    *domain = '\0';
    return (domain > start); // Returns 1 if we actually wrote characters
}

void *process_file(void *arg) {
    ThreadData *data = (ThreadData *)arg;

    data->domains_hash = calloc(HASH_SIZE, sizeof(Node *));
    data->sitemaps_hash = calloc(HASH_SIZE, sizeof(Node *));
    if (!data->domains_hash || !data->sitemaps_hash) {
        perror("Thread table allocation failed");
        exit(EXIT_FAILURE);
    }

    FILE *file = fopen(data->filename, "r");
    if (!file) {
        fprintf(stderr, "Error opening file: %s\n", data->filename);
        return NULL;
    }

    char line[MAX_LINE];
    char domain[MAX_LINE];
    char sub_sitemap[MAX_LINE];

    while (fgets(line, sizeof(line), file)) {
        // Fast custom TSV scanning instead of destructive strtok
        char *col1 = line;
        char *tab1 = strchr(col1, '\t');
        if (!tab1) continue;

        char *col2 = tab1 + 1;
        char *tab2 = strchr(col2, '\t');
        if (!tab2) continue;

        // Extract sub_sitemap column safely without altering original line stream
        size_t sitemap_len = tab2 - col2;
        if (sitemap_len >= MAX_LINE) sitemap_len = MAX_LINE - 1;
        memcpy(sub_sitemap, col2, sitemap_len);
        sub_sitemap[sitemap_len] = '\0';

        // Add unique sitemap
        if (insert(data->sitemaps_hash, sub_sitemap)) {
            data->unique_sitemaps++;
        }

        // Extract and add unique domain from col1
        if (extract_domain(col1, domain)) {
            if (insert(data->domains_hash, domain)) {
                data->unique_domains++;
            }
        }
    }

    fclose(file);
    return NULL;
}

void free_table(Node **table) {
    for (int i = 0; i < HASH_SIZE; i++) {
        Node *curr = table[i];
        while (curr != NULL) {
            Node *temp = curr;
            curr = curr->next;
            free(temp->str);
            free(temp);
        }
    }
    free(table);
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <file1.tsv> [file2.tsv ...]\n", argv);
        return EXIT_FAILURE;
    }

    int num_files = argc - 1;
    pthread_t *threads = malloc(num_files * sizeof(pthread_t));
    ThreadData *thread_data = malloc(num_files * sizeof(ThreadData));

    printf("Spawning %d threads for processing...\n", num_files);

    for (int i = 0; i < num_files; i++) {
        thread_data[i].filename = argv[i + 1];
        thread_data[i].unique_domains = 0;
        thread_data[i].unique_sitemaps = 0;
        pthread_create(&threads[i], NULL, process_file, &thread_data[i]);
    }

    for (int i = 0; i < num_files; i++) {
        pthread_join(threads[i], NULL);
    }

    printf("Merging results...\n");

    Node **final_domains = calloc(HASH_SIZE, sizeof(Node *));
    Node **final_sitemaps = calloc(HASH_SIZE, sizeof(Node *));
    long long total_unique_domains = 0;
    long long total_unique_sitemaps = 0;

    for (int i = 0; i < num_files; i++) {
        for (int h = 0; h < HASH_SIZE; h++) {
            Node *curr = thread_data[i].domains_hash[h];
            while (curr != NULL) {
                if (insert(final_domains, curr->str)) {
                    total_unique_domains++;
                }
                curr = curr->next;
            }
            curr = thread_data[i].sitemaps_hash[h];
            while (curr != NULL) {
                if (insert(final_sitemaps, curr->str)) {
                    total_unique_sitemaps++;
                }
                curr = curr->next;
            }
        }
        free_table(thread_data[i].domains_hash);
        free_table(thread_data[i].sitemaps_hash);
    }

    printf("\n=====================================\n");
    printf("FINAL VERIFIED REPORT\n");
    printf("=====================================\n");
    printf("Total Unique Domains:  %lld\n", total_unique_domains);
    printf("Total Unique Sitemaps: %lld\n", total_unique_sitemaps);
    printf("=====================================\n");

    free_table(final_domains);
    free_table(final_sitemaps);
    free(threads);
    free(thread_data);

    return EXIT_SUCCESS;
}

Community

Join https://t.me/nlp_uk