<commit_before>#include "ruby.h"
#include <string.h>
#define NUM_CHILDREN 256
#define INITIAL_STR_LEN 32
#define INCREMENT_STR_LEN 32

typedef struct _trie Trie;
struct _trie {
    char c;
    Trie *next;
    Trie *child;
    VALUE value;
};

typedef VALUE (*TRAVERSE_FUNC)(const Trie *node);
typedef VALUE (*TRAVERSE_WITH_KEY_FUNC)(const Trie *node, const char *key);

/***** Trie Operation *****/
static Trie*
trie_new(void)
{
    Trie *trie = ALLOC(Trie);
    trie->c = 0;
    trie->next = NULL;
    trie->child = NULL;
    trie->value = 0;
    return trie;
}

static void
trie_free(Trie *trie)
{
    if (trie) {
        if (trie->next) {
            trie_free(trie->next);
        }
        if (trie->child) {
            trie_free(trie->child);
        }
        ruby_xfree(trie);
    }
}

static Trie *
trie_add_child(Trie *trie, Trie *child)
{
    if (trie->child) {
        child->next = trie->child;
        trie->child = child;
    } else {
        trie->child = child;
    }
    return child;
}

static Trie *
trie_find(Trie *start, const char key)
{
    Trie *node;
    for (node = start; node != NULL && node->c != key; node = node->next);
    return node;
}

static Trie *
trie_create(Trie *trie, const char *key)
{
    const size_t key_len = strlen(key);
    Trie *node = trie;
    for (size_t i = 0; i < key_len; ++i) {
        const char k = key[i];
        Trie *child = trie_find(node->child, k);
        if (!child) {
            child = trie_new();
            child->c = k;
            trie_add_child(node, child);
        }
        node = child;
    }
    return node;
}

static Trie*
trie_search(Trie* trie, const char *key)
{
    Trie *node = trie;
    const size_t key_len = strlen(key);
    for (size_t i = 0; i < key_len; ++i) {
        const char k = key[i];
        if (node->c == k) {
            node = trie_find(node->next, k);
        } else {
            node = trie_find(node->child, k);
        }
    }
    return node;
}

static Trie*
trie_search_leaf(Trie* trie, const char *key)
{
    Trie* result = trie_search(trie, key);
    if (!result || !result->value)
        return NULL;
    return result;
}

static void
trie_traverse(Trie* trie, TRAVERSE_FUNC func)
{
    if (trie) {
        if (trie->value) {
            func(trie);
        }
        for (Trie *node = trie->child; node != NULL; node = node->next) {
            trie_traverse(node, func);
        }
    }
}

static void
trie_traverse_with_key(Trie *trie, const char *key, TRAVERSE_WITH_KEY_FUNC func)
{
    if (trie) {
        const size_t key_len = strlen(key);
        char *tmp_key = ALLOC_N(char, key_len + 2);
        strcpy(tmp_key, key);
        tmp_key[key_len] = trie->c;
        if (trie->value) {
            func(trie, tmp_key);
        }
        for (Trie *node = trie->child; node != NULL; node = node->next) {
            trie_traverse_with_key(node, tmp_key, func);
        }
    }
}

static unsigned long
trie_count(Trie *trie)
{
    unsigned long count = 0;
    if (trie->value) {
        ++count;
    }
    for (Trie *node = trie->next; node != NULL; node = node->next) {
        count += trie_count(node);
    }
    for (Trie *node = trie->child; node != NULL; node = node->next) {
        count += trie_count(node);
    }
    return count;
}

/***** Helper function *****/
static VALUE<commit_msg>Fix the behavior of count function.<commit_after>#include "ruby.h"
#include <string.h>
#define NUM_CHILDREN 256
#define INITIAL_STR_LEN 32
#define INCREMENT_STR_LEN 32

typedef struct _trie Trie;
struct _trie {
    char c;
    Trie *next;
    Trie *child;
    VALUE value;
};

typedef VALUE (*TRAVERSE_FUNC)(const Trie *node);
typedef VALUE (*TRAVERSE_WITH_KEY_FUNC)(const Trie *node, const char *key);

/***** Trie Operation *****/
static Trie*
trie_new(void)
{
    Trie *trie = ALLOC(Trie);
    trie->c = 0;
    trie->next = NULL;
    trie->child = NULL;
    trie->value = 0;
    return trie;
}

static void
trie_free(Trie *trie)
{
    if (trie) {
        if (trie->next) {
            trie_free(trie->next);
        }
        if (trie->child) {
            trie_free(trie->child);
        }
        ruby_xfree(trie);
    }
}

static Trie *
trie_add_child(Trie *trie, Trie *child)
{
    if (trie->child) {
        child->next = trie->child;
        trie->child = child;
    } else {
        trie->child = child;
    }
    return child;
}

static Trie *
trie_find(Trie *start, const char key)
{
    Trie *node;
    for (node = start; node != NULL && node->c != key; node = node->next);
    return node;
}

static Trie *
trie_create(Trie *trie, const char *key)
{
    const size_t key_len = strlen(key);
    Trie *node = trie;
    for (size_t i = 0; i < key_len; ++i) {
        const char k = key[i];
        Trie *child = trie_find(node->child, k);
        if (!child) {
            child = trie_new();
            child->c = k;
            trie_add_child(node, child);
        }
        node = child;
    }
    return node;
}

static Trie*
trie_search(Trie* trie, const char *key)
{
    Trie *node = trie;
    const size_t key_len = strlen(key);
    for (size_t i = 0; i < key_len; ++i) {
        const char k = key[i];
        if (node->c == k) {
            node = trie_find(node->next, k);
        } else {
            node = trie_find(node->child, k);
        }
    }
    return node;
}

static Trie*
trie_search_leaf(Trie* trie, const char *key)
{
    Trie* result = trie_search(trie, key);
    if (!result || !result->value)
        return NULL;
    return result;
}

static void
trie_traverse(Trie* trie, TRAVERSE_FUNC func)
{
    if (trie) {
        if (trie->value) {
            func(trie);
        }
        for (Trie *node = trie->child; node != NULL; node = node->next) {
            trie_traverse(node, func);
        }
    }
}

static void
trie_traverse_with_key(Trie *trie, const char *key, TRAVERSE_WITH_KEY_FUNC func)
{
    if (trie) {
        const size_t key_len = strlen(key);
        char *tmp_key = ALLOC_N(char, key_len + 2);
        strcpy(tmp_key, key);
        tmp_key[key_len] = trie->c;
        if (trie->value) {
            func(trie, tmp_key);
        }
        for (Trie *node = trie->child; node != NULL; node = node->next) {
            trie_traverse_with_key(node, tmp_key, func);
        }
    }
}

static unsigned long
trie_count(Trie *trie)
{
    unsigned long count = 0;
    if (trie->value) {
        ++count;
    }
    for (Trie *node = trie->child; node != NULL; node = node->next) {
        count += trie_count(node);
    }
    return count;
}

/***** Helper function *****/
static VALUE
{'fraction_non_alphanumeric': 0.14235581324382057, 'fraction_numerical': 0.003967043027158987, 'mean_word_length': 2.1835842642059253, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3028045', 'n_tokens_mistral': 2513, 'n_tokens_neox': 2458, 'n_words': 598}