/* Pop a key from dict, NULL on not found. */ void * dict_ipop(struct dict *dict, char *key, size_t len) { assert(dict != NULL); size_t index = dict_table_idx(dict->idx, key, len); struct dict_node *node = (dict->table)[index]; struct dict_node *prev = NULL; while (node != NULL) { if (dict_key_equals(node->key, node->len, key, len)) { if (prev == NULL) { (dict->table)[index] = node->next; } else { prev->next = node->next; } void *val = node->val; dict_node_free(node); dict->len -= 1; return val; } prev = node; node = node->next; } return NULL; }
/* Resize and rehash dict. */ int dict_resize(struct dict *dict) { assert(dict != NULL && dict->idx <= dict_idx_max); size_t new_idx = dict->idx + 1; if (new_idx > dict_idx_max) return DICT_ENOMEM; size_t new_table_size = dict_table_sizes[new_idx]; struct dict_node **new_table = malloc( new_table_size * sizeof(struct dict_node *)); /* init table to all NULL */ size_t index; for (index = 0; index < new_table_size; index++) new_table[index] = NULL; size_t table_size = dict_table_sizes[dict->idx]; for (index = 0; index < table_size; index++) { struct dict_node *node = (dict->table)[index]; while (node != NULL) { struct dict_node *new_node = dict_node_new( node->key, node->len, node->val); if (new_node == NULL) return DICT_ENOMEM; size_t new_index = dict_table_idx( new_idx, new_node->key, new_node->len); struct dict_node *cursor = new_table[new_index]; if (cursor == NULL) { /* set as head node */ new_table[new_index] = new_node; } else { while (cursor->next != NULL) cursor = cursor->next; /* set as last node */ cursor->next = new_node; } /* shift next */ struct dict_node *next = node->next; dict_node_free(node); node = next; } } free(dict->table); dict->table = new_table; dict->idx = new_idx; return DICT_OK; }
/* Clear dict. */ void dict_clear(struct dict *dict) { assert(dict != NULL && dict->idx <= dict_idx_max); size_t index; size_t table_size = dict_table_sizes[dict->idx]; for (index = 0; index < table_size; index++) { struct dict_node *node = (dict->table)[index]; while (node != NULL) { struct dict_node *next = node->next; dict_node_free(node); dict->len -= 1; node = next; } (dict->table)[index] = NULL; } }