Beispiel #1
0
sexpr lx_make_environment (sexpr env)
{
    static struct memory_pool pool
            = MEMORY_POOL_INITIALISER(sizeof (struct environment));
    struct environment *rv;
    struct tree_node *n;
    int_pointer hash = hash_murmur2_pt ((void *)&env, sizeof(env), 0);
    /* note: the hashing may seem pointless, but it does help performance by
     * effectively randomising the input data, thus helping the tree performance
     * by making it far less likely for the tree to degenerate into a linked
     * list. */

    if ((n = tree_get_node (&environment_tree, hash)))
    {
        return (sexpr)node_get_value (n);
    }

    rv = get_pool_mem (&pool);

    if (rv == (struct environment *)0)
    {
        return sx_nonexistent;
    }

    rv->type        = environment_type_identifier;
    rv->environment = env;

    tree_add_node_value (&environment_tree, hash, (void *)rv);

    return (sexpr)rv;
}
Beispiel #2
0
/*@null@*/ static node_t list_get_node_by_value(list_t inst, void* val) {
	node_t n = inst->head;
	int ctr = 0;
	while ((n != NULL) && (inst->cmp(node_get_value(n), val))) {
		ctr++;
		n = n->next;
	}
	return n;
}
Beispiel #3
0
/*@null@*/ void* iter_get(iter_t inst) {
	void* rval = NULL;
	node_t node;

	node = iter_get_node(inst);
	if (node != NULL) {
		rval = node_get_value(iter_get_node(inst));
	}

	return rval;
}
Beispiel #4
0
int list_index_of(list_t inst, void* val) {
	node_t n = inst->head;
	int rval = 0;
	while ((n != NULL) && (inst->cmp(node_get_value(n), val))) {
		rval++;
		n = n->next;
	}
	if (n == NULL) {
		rval = -1;
	}
	return rval;
}
Beispiel #5
0
static unsigned int test_tree_value(unsigned int keys) {
    struct tree *t = tree_create ();
    unsigned int i;
    struct tree_node *n;

    for (i = 0; i < keys; i++) {
        tree_add_node_value (t, i, sentinelvalue(i));
    }

    for (i = 0; i < keys; i++) {
        n = tree_get_node (t, i);

        if (n == (struct tree_node *)0) {
            tree_destroy(t);
            return 7;
        }
        if (n->key != i) {
            tree_destroy(t);
            return 8;
        }
        if (node_get_value (n) != sentinelvalue(i)) {
            tree_destroy(t);
            return 9;
        }
    }

    n = tree_get_node (t, keys + 1);
    if (n != (struct tree_node *)0) {
        tree_destroy(t);
        return 10;
    }

    /* we do this twice to stress the optimising algo once it's in */

    for (i = 0; i < keys; i++) {
        n = tree_get_node (t, i);

        if (n == (struct tree_node *)0) {
            tree_destroy(t);
            return 11;
        }
        if (n->key != i) {
            tree_destroy(t);
            return 12;
        }
        if (node_get_value (n) != sentinelvalue(i)) {
            tree_destroy(t);
            return 13;
        }
    }

    n = tree_get_node (t, keys + 1);
    if (n != (struct tree_node *)0) {
        tree_destroy(t);
        return 14;
    }

    tree_destroy(t);

    return 0;
}
Beispiel #6
0
const void *immutable (const void * data, unsigned long length)
{
    const char *rv;
    const char *data_char = (const char *)data;
    struct tree_node *n;
    int_pointer hash = hash_murmur2_pt (&data, sizeof (const void *), 0);

    if (tree_get_node (&immutable_data_tree, hash)
        != (struct tree_node *)0)
    {
        return data;
    }

    hash = hash_murmur2_pt (data, length, 0);

    if ((n = tree_get_node (&immutable_hashes, hash))
        != (struct tree_node *)0)
    {
        return (const void *)node_get_value (n);
    }

    if ((length + 1) > immutable_data_space_left) {
        unsigned long new_size = IMMUTABLE_CHUNKSIZE;
        lock_immutable_pages();

        if (length > IMMUTABLE_CHUNKSIZE) {
            new_size = ((length / IMMUTABLE_CHUNKSIZE) +
                         (((length % IMMUTABLE_CHUNKSIZE) != 0) ? 1 : 0))
                       * IMMUTABLE_CHUNKSIZE;
        }

        if (immutable_data != (void *)0)
        {
            lock_immutable_pages();
        }

        immutable_data = get_mem(new_size);

        immutable_data_space_left = new_size;
        immutable_cursor = immutable_data;
        immutable_data_size = new_size;
    }

    for (rv = immutable_cursor; length != 0;
         immutable_cursor++,
         data_char++,
         length--,
         immutable_data_space_left--)
    {
         *immutable_cursor = *data_char;
    }

    *immutable_cursor = 0; /* write an extra 0 after whatever we just wrote */
    immutable_cursor++;
    immutable_data_space_left--;

    while ((((unsigned long)immutable_cursor) % sizeof(void *)) != 0)
    {
        *immutable_cursor = 0;
        immutable_cursor++;
        immutable_data_space_left--;
    }

    tree_add_node_value (&immutable_hashes, hash, (void *)rv);

    hash = hash_murmur2_pt (&rv, sizeof (const void *), 0);

    tree_add_node (&immutable_data_tree, hash);

    return rv;
}
Beispiel #7
0
static unsigned int test_tree_node_removal(unsigned int keys) {
    struct tree *t = tree_create ();
    unsigned int i;
    struct tree_node *n;

    for (i = 0; i < keys; i++) {
        tree_add_node_value (t, i, sentinelvalue(i));
    }

    /* remove half the nodes */
    for (i = 0; i < keys; i+=2) {
        tree_remove_node (t, i);
    }

    /* search for the nodes that should still be present */
    for (i = 1; i < keys; i+=2) {
        n = tree_get_node (t, i);

        if (n == (struct tree_node *)0) {
            tree_destroy(t);
            return 15;
        }
        if (n->key != i) {
            tree_destroy(t);
            return 16;
        }
        if (node_get_value (n) != sentinelvalue(i)) {
            tree_destroy(t);
            return 17;
        }
    }

    /* search for the nodes that should be missing */
    for (i = 0; i < keys; i+=2) {
        n = tree_get_node (t, i);

        if (n != (struct tree_node *)0) {
            tree_destroy(t);
            return 18;
        }
    }

    /* search for an arbitrary node that can't be present */
    n = tree_get_node (t, keys + 1);
    if (n != (struct tree_node *)0) {
        tree_destroy(t);
        return 19;
    }

    /* we do the searches twice to stress the optimising algo once it's in */

    /* search for the nodes that should still be present */
    for (i = 1; i < keys; i+=2) {
        n = tree_get_node (t, i);

        if (n == (struct tree_node *)0) {
            tree_destroy(t);
            return 20;
        }
        if (n->key != i) {
            tree_destroy(t);
            return 21;
        }
        if (node_get_value (n) != sentinelvalue(i)) {
            tree_destroy(t);
            return 22;
        }
    }

    /* search for the nodes that should be missing */
    for (i = 0; i < keys; i+=2) {
        n = tree_get_node (t, i);

        if (n != (struct tree_node *)0) {
            tree_destroy(t);
            return 23;
        }
    }

    /* remove the remaining nodes */
    for (i = 1; i < keys; i+=2) {
        tree_remove_node (t, i);
    }

    if (t->root != (struct tree_node *)0) {
        tree_destroy(t);
        return 24;
    }

    tree_destroy(t);

    return 0;
}
Beispiel #8
0
/*@null@*/ static char* node_to_string(node_t inst) {
	char rval[256];
	snprintf(rval, sizeof(rval), "(node_t) { val=%p }", node_get_value(inst));
	return strdup(rval);
}
Beispiel #9
0
/*@null@*/ void* list_get(list_t inst, int idx) {
	node_t n = list_get_node_by_index(inst, idx);
	return node_get_value(n);
}
Beispiel #10
0
/*@null@*/ static void* node_exit(node_t inst) {
	void* rval = node_get_value(inst);
	//printf("exit node@%p\n", inst);
	free(inst);
	return rval;
}