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; }
void func_dict_union(void) { cData * args; cDict * dict1, * dict2, *d; if (!func_init_2(&args, DICT, DICT)) return; dict1 = dict_dup(DICT1); dict2 = dict_dup(DICT2); pop(2); /* dict_union will discard the dicts */ d = dict_union(dict1, dict2); push_dict(d); dict_discard(d); }
cDict *dict_new_empty(void) { if (!generic_empty_dict) { cList *l1, *l2; l1 = list_new(0); l2 = list_new(0); generic_empty_dict = dict_new(l1, l2); list_discard(l1); list_discard(l2); } return dict_dup(generic_empty_dict); }