/* 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; }
/* Test if a key is in dict. */ int dict_ihas(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]; while (node != NULL) { if (dict_key_equals(node->key, node->len, key, len)) return 1; node = node->next; } return 0; }
/* Set a key into dict. */ int dict_iset(struct dict *dict, char *key, size_t len, void *val) { assert(dict != NULL); if ((dict_table_sizes[dict->idx] * DICT_LOAD_LIMIT < dict->len + 1) && dict_resize(dict) != DICT_OK) return DICT_ENOMEM; size_t index = dict_table_idx(dict->idx, key, len); struct dict_node *node = (dict->table)[index]; /* try to find this key. */ while (node != NULL) { if (dict_key_equals(node->key, node->len, key, len)) { node->key = key; node->len = len; node->val = val; return DICT_OK; } node = node->next; } /* create node if not found */ struct dict_node *new_node = dict_node_new(key, len, val); if (new_node == NULL) return DICT_ENOMEM; /* rewind to list head */ node = (dict->table)[index]; if (node == NULL) { /* if list is empty, set as head node */ (dict->table)[index] = new_node; } else { /* else append as tail node */ while (node->next != NULL) node = node->next; node->next = new_node; } dict->len += 1; return DICT_OK; }