Ejemplo n.º 1
0
cDict *dict_new(cList *keys, cList *values)
{
    cDict *cnew;
    Int i, j, size;

    if (generic_empty_dict && list_length(keys) == 0)
        return dict_dup(generic_empty_dict);

    /* Construct a new dictionary. */
    cnew = tmalloc(sizeof(cDict));

    cnew->keys   = list_dup(keys);
    cnew->values = list_dup(values);

    /* Calculate initial size of chain and hash table. */
    cnew->hashtab_size = HASHTAB_STARTING_SIZE;
    while (cnew->hashtab_size < keys->len) {
        if (cnew->hashtab_size > 4096)
            cnew->hashtab_size += 4096;
        else
            cnew->hashtab_size = cnew->hashtab_size * 2 + MALLOC_DELTA;
    }

    /* Initialize chain entries and hash table. */
    size = sizeof(Int) * cnew->hashtab_size;
    cnew->links   = tmalloc(size);
    cnew->hashtab = tmalloc(size);
    memset(cnew->links,   -1, size);
    memset(cnew->hashtab, -1, size);

    /* Insert the keys into the hash table, eliminating duplicates. */
    i = j = 0;
    while (i < cnew->keys->len) {
        if (i != j) {
            cnew->keys->el[j] = cnew->keys->el[i];
            cnew->values->el[j] = cnew->values->el[i];
        }
        if (search(cnew, &keys->el[i]) == F_FAILURE) {
            insert_key(cnew, j++);
        } else {
            data_discard(&cnew->keys->el[i]);
            data_discard(&cnew->values->el[i]);
        }
        i++;
    }
    cnew->keys->len = cnew->values->len = j;

    cnew->refs = 1;

    if (!generic_empty_dict && list_length(keys) == 0)
        generic_empty_dict = dict_dup(cnew);

    return cnew;
}
Ejemplo n.º 2
0
void discard_handled (cData *d)
{
    HandledFrob *h = HANDLED_FROB(d);

    data_discard(&h->rep);
    ident_discard(h->handler);
}
Ejemplo n.º 3
0
Hash * hash_new_with(cList *keys) {
    Hash *cnew;
    Int i, j;

    /* Construct a new hash */
    cnew = EMALLOC(Hash, 1);
    cnew->keys = list_dup(keys);

    /* Calculate initial size of chain and hash table. */
    cnew->hashtab_size = HASHTAB_STARTING_SIZE;
    while (cnew->hashtab_size < keys->len)
	cnew->hashtab_size = cnew->hashtab_size * 2 + MALLOC_DELTA;

    /* Initialize chain entries and hash table. */
    cnew->links   = EMALLOC(Int, cnew->hashtab_size);
    cnew->hashtab = EMALLOC(Int, cnew->hashtab_size);
    memset(cnew->links,   -1, sizeof(Long)*cnew->hashtab_size);
    memset(cnew->hashtab, -1, sizeof(Long)*cnew->hashtab_size);

    /* Insert the keys into the hash table, eliminating duplicates. */
    i = j = 0;
    while (i < cnew->keys->len) {
	if (i != j)
	    cnew->keys->el[j] = cnew->keys->el[i];
	if (hash_find(cnew, &keys->el[i]) == F_FAILURE)
	    quickhash_insert_key(cnew, j++);
	else
	    data_discard(&cnew->keys->el[i]);
	i++;
    }
    cnew->keys->len = j;

    cnew->refs = 1;
    return cnew;
}
Ejemplo n.º 4
0
Archivo: list.c Proyecto: nrhtr/genesis
cList *list_prep(cList * list, Int start, Int len)
{
    cList *cnew;
    Int i, resize, size;

    /* Figure out if we need to resize the list or move its contents.  Moving
     * contents takes precedence. */
#if DISABLED
    resize = (len - start) * 4 < list->size;
    resize = resize && list->size > STARTING_SIZE;
    resize = resize || (list->size < len);
#endif
    resize = list->size < len + start;


    /* Move the list contents into a new list. */
    if ((list->refs > 1) || (resize && start > 0)) {
        cnew = list_new(len);
        cnew->len = len;
        len = (list->len < len) ? list->len : len;
        for (i = 0; i < len; i++)
            data_dup(&cnew->el[i], &list->el[start + i]);
        list_discard(list);
        return cnew;
    }

    /* Resize the list.  We can assume that list->start == start == 0. */
    else if (resize) {
        for (; list->len > len; list->len--)
            data_discard(&list->el[list->len - 1]);
        list->len = len;
        size = len;
        list = (cList *) erealloc(list, sizeof(cList) + (size * sizeof(cData)));
        list->size = size;
        return list;
    }

    else {
        for (; list->start < start; list->start++, list->len--)
            data_discard(&list->el[list->start]);
        for (; list->len > len; list->len--)
            data_discard(&list->el[list->start + list->len - 1]);
        list->start = start;
        list->len = len;
        return list;
    }
}
Ejemplo n.º 5
0
Archivo: list.c Proyecto: nrhtr/genesis
/* Warning: do not discard a list before initializing its data elements. */
void list_discard(cList * list)
{
    Int i;

    if (!--list->refs) {
        for (i = list->start; i < list->start + list->len; i++)
            data_discard(&list->el[i]);
        efree(list);
    }
}
Ejemplo n.º 6
0
Archivo: list.c Proyecto: nrhtr/genesis
/* Error-checking on pos is the job of the calling function. */
cList *list_replace(cList * list, Int pos, cData * elem)
{
    /* list_prep needed here only for multiply referenced lists */
    if (list->refs > 1)
        list = list_prep(list, list->start, list->len);
    pos += list->start;
    data_discard(&list->el[pos]);
    data_dup(&list->el[pos], elem);
    return list;
}
Ejemplo n.º 7
0
Archivo: list.c Proyecto: nrhtr/genesis
/* Error-checking on pos is the job of the calling function. */
cList *list_delete(cList * list, Int pos)
{
    /* Special-case deletion of last element. */
    if (pos == list->len - 1)
        return list_prep(list, list->start, list->len - 1);

    /* list_prep needed here only for multiply referenced lists */
    if (list->refs > 1)
        list = list_prep(list, list->start, list->len);

    pos += list->start;
    data_discard(&list->el[pos]);
    MEMMOVE(list->el + pos, list->el + pos + 1, list->len - pos);
    list->len--;

    /* list_prep needed here only if list has shrunk */
    if (((list->len - list->start) * 4 < list->size)
        && (list->size > STARTING_SIZE))
        list = list_prep(list, list->start, list->len);

    return list;
}
Ejemplo n.º 8
0
Archivo: math.c Proyecto: nrhtr/genesis
/* which is 1 for max, -1 for min. */
INTERNAL void find_extreme(Int which)
{
    Int arg_start, num_args, i, type;
    cData *args, *extreme, d;

    arg_start = arg_starts[--arg_pos];
    args = &stack[arg_start];
    num_args = stack_pos - arg_start;

    if (!num_args) {
        cthrow(numargs_id, "Called with no arguments, requires at least one.");
        return;
    }

    type = args[0].type;
    if (type != INTEGER && type != STRING && type != FLOAT) {
        cthrow(type_id, "First argument (%D) not an integer, float or string.", &args[0]);
        return;
    }

    extreme = &args[0];
    for (i = 1; i < num_args; i++) {
        if (args[i].type != type) {
            cthrow(type_id, "Arguments are not all of same type.");
            return;
        }
        if (data_cmp(&args[i], extreme) * which > 0)
            extreme = &args[i];
    }

    /* Replace args[0] with extreme, and pop other arguments. */
    data_dup(&d, extreme);
    data_discard(&args[0]);
    args[0] = d;
    pop(num_args - 1);
}