Beispiel #1
0
void *core_map_add(struct core_map *self, void *key)
{
#ifdef CORE_MAP_ALIGNMENT_ENABLED
    key = core_map_pad_key(self, key);
#endif

    return core_dynamic_hash_table_add(&self->table, key);
}
Beispiel #2
0
void *core_dynamic_hash_table_add(struct core_dynamic_hash_table *self, void *key)
{
    float ratio;
    float threshold;
    void *bucket;
    void *new_bucket;
    int value_size;

    /* if no resize is in progress, the load is verified
     */
    if (!self->resize_in_progress) {

        threshold = self->resize_load_threshold;
        ratio = (0.0 + core_hash_table_size(self->current)) / core_hash_table_buckets(self->current);

        if (ratio < threshold) {
            /* there is still place in the table.
             */
            return core_hash_table_add(self->current, key);

        } else {

            /* the resizing must begin
             */
#ifdef CORE_DYNAMIC_HASH_TABLE_DEBUG_ADD
            printf("DEBUG core_dynamic_hash_table_add start resizing\n");
#endif

            core_dynamic_hash_table_start_resizing(self);

            /* perform a fancy recursive call
             */
            return core_dynamic_hash_table_add(self, key);
        }
    }

    /* if the resizing finished, just add the item to current
     */
    if (core_dynamic_hash_table_resize(self)) {
        return core_hash_table_add(self->current, key);
    }

    /*
     * the next table has the key
     * don't add anything.
     */
    bucket = core_hash_table_get(self->next, key);
    if (bucket != NULL) {
        return bucket;
    }

    /*
     * Otherwise, check if it is in the old one
     */

    bucket = core_hash_table_get(self->current, key);

    /*
     * If it is not in the current, simply add it to
     * the next
     */
    if (bucket == NULL) {
        return core_hash_table_add(self->next, key);
    }

    /* Otherwise, add it to the next, copy the value,
     * and return the bucket from next
     */

    new_bucket = core_hash_table_add(self->next, key);
    value_size = core_hash_table_value_size(self->current);

    if (value_size > 0) {
        core_memory_copy(new_bucket, bucket, value_size);
    }

    self->resize_current_size--;

    return new_bucket;
}
int main(int argc, char **argv)
{
    BEGIN_TESTS();

    {
        struct core_dynamic_hash_table table;
        uint64_t i;
        uint64_t elements;

        elements = 900;
        core_dynamic_hash_table_init(&table, 1140, sizeof(int), 0);

        for (i = 0; i < elements; i++) {
            /*
            printf("insert %d\n", i);

            printf("before actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i);
            */
            TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i);

            core_dynamic_hash_table_add(&table, &i);

            /*
            printf("after1 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1);
            */
            TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1);
            /*
            printf("after2 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1);
            */
            TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1);
            /*
            printf("after3 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1);
            */
            TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1);
            /*
            printf("after4 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1);
            */
            TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1);
            /*
            printf("after5 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1);
            */
            TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1);
            /*
            printf("after6 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1);
            */
        }

        core_dynamic_hash_table_destroy(&table);
    }

    {
        struct core_dynamic_hash_table table;
        struct core_dynamic_hash_table_iterator iterator;
        int key_size;
        int value_size;
        uint64_t buckets;
        uint64_t i;
        int j;
        uint64_t inserted;
        int key;
        int *key_bucket;
        int *value_bucket;
        int found;

        key_size = sizeof(int);
        value_size = sizeof(int);
        buckets = 4;
        inserted = 0;

        core_dynamic_hash_table_init(&table, buckets, key_size, value_size);

        for (i = 0; i < buckets; i++) {
            key = inserted;
            value_bucket = core_dynamic_hash_table_add(&table, &key);
            inserted++;

            TEST_POINTER_NOT_EQUALS(value_bucket, NULL);

            *value_bucket = i;

            TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), inserted);

            value_bucket = core_dynamic_hash_table_get(&table, &key);

            TEST_POINTER_NOT_EQUALS(value_bucket, NULL);
        }

        key = inserted;
        value_bucket = core_dynamic_hash_table_add(&table, &key);
        inserted++;

        for (j = 0; j < 1000; j++) {
            for (i = 0; i < buckets; i++) {
                key = inserted;
                value_bucket = core_dynamic_hash_table_add(&table, &key);
                inserted++;

                TEST_POINTER_NOT_EQUALS(value_bucket, NULL);

                *value_bucket = i;

                /*
                printf("DEBUG actual %d expected %d\n",
                                (int)core_dynamic_hash_table_size(&table), inserted);
                                */

                TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), inserted);

                value_bucket = core_dynamic_hash_table_get(&table, &key);

                TEST_POINTER_NOT_EQUALS(value_bucket, NULL);
            }
        }

        key = 9999;
        value_bucket = core_dynamic_hash_table_add(&table, &key);
        *value_bucket = 8888;

        core_dynamic_hash_table_iterator_init(&iterator, &table);

        i = 0;
        found = 0;

        while (core_dynamic_hash_table_iterator_has_next(&iterator)) {
            core_dynamic_hash_table_iterator_next(&iterator, (void **)&key_bucket,
                                                  (void **)&value_bucket);

            if (*key_bucket == 9999 && *value_bucket == 8888) {
                found = 1;
            }
            i++;
        }

        TEST_UINT64_T_EQUALS(i, core_dynamic_hash_table_size(&table));
        TEST_INT_EQUALS(found, 1);

        core_dynamic_hash_table_iterator_destroy(&iterator);

        core_dynamic_hash_table_destroy(&table);
    }

    {
        struct core_dynamic_hash_table table;
        int key;
        int *value;

        /*
        printf("-------------------\n");
        printf("DEBUG TEST-alpha-89\n");
        */

        core_dynamic_hash_table_init(&table, 8, sizeof(int), sizeof(int));

        for (key = 0; key < 1000000; key++) {

            /*
                        printf("DEBUG key %d\n", key);
                        */
            core_dynamic_hash_table_add(&table, &key);

            value = (int *)core_dynamic_hash_table_get(&table, &key);

            TEST_POINTER_NOT_EQUALS(value, NULL);

            *value = key;
        }

        core_dynamic_hash_table_destroy(&table);
    }

    {
        struct core_dynamic_hash_table table;
        uint64_t i;

        core_dynamic_hash_table_init(&table, 2, sizeof(int), sizeof(int));

        for (i = 0; i < 999; i++) {

            core_dynamic_hash_table_add(&table, &i);

            TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1);
        }

        core_dynamic_hash_table_destroy(&table);
    }

    {
        struct core_dynamic_hash_table table;
        uint64_t i;
        void *bucket;

        core_dynamic_hash_table_init(&table, 2, sizeof(int), 128);

        for (i = 0; i < 999; i++) {

            core_dynamic_hash_table_add(&table, &i);

            TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1);
        }

        for (i = 0; i < 999; i++) {
            bucket = core_dynamic_hash_table_get(&table, &i);

            TEST_POINTER_NOT_EQUALS(bucket, NULL);
        }

        core_dynamic_hash_table_destroy(&table);

    }

    END_TESTS();

    return 0;
}