Beispiel #1
0
/* Add an element to the target hash table */
int dictAdd(dict *d, void *key, void *val)
{
    int index;
    dictEntry *entry;
    dictht *ht;

    if (dictIsRehashing(d)) _dictRehashStep(d);

    /* Get the index of the new element, or -1 if
     * the element already exists. */
    if ((index = _dictKeyIndex(d, key)) == -1)
        return DICT_ERR;

    /* Allocates the memory and stores key */
    ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
    entry = zmalloc(sizeof(*entry));
    entry->next = ht->table[index];
    ht->table[index] = entry;
    ht->used++;

    /* Set the hash entry fields. */
    dictSetHashKey(d, entry, key);
    dictSetHashVal(d, entry, val);
    return DICT_OK;
}
/* 添加元素的底层实现函数(由 dictAdd 调用)
 * 
 * 新元素的添加操作被分为两步:
 * 1) 创建节点并设置节点的 key ,然后返回节点
 * 2) 设置节点的值
 * 这个函数执行第一步,第二步由函数 dictSetVal 进行
 * 
 * Args:
 *  d 字典
 *  key 新节点的关键字
 *
 * Returns:
 *  NULL 关键字已经存在
 *  entry 设置了关键字的新节点,返回给调用者进行进一步的处理
 */
dictEntry *dictAddRaw(dict *d, void *key)
{
    int index;
    dictEntry *entry;
    dictht *ht;

    // 检查字典(的哈希表)能否执行 rehash 操作
    // 如果可以的话,执行平摊 rehash 操作
    if (dictIsRehashing(d)) _dictRehashStep(d);

    // 计算 key 的 index 值
    // 如果 key 已经存在,_dictKeyIndex 返回 -1 
    if ((index = _dictKeyIndex(d, key)) == -1)
        return NULL;

    // 如果字典正在进行 rehash ,那么将新元素添加到 1 号哈希表,
    // 否则,使用 0 号哈希表
    ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];

    entry = zmalloc(sizeof(*entry));    // 为新节点分配内存
    entry->next = ht->table[index];     // 调整节点的 next 指针
    ht->table[index] = entry;           // 然后将新节点设为链头
    ht->used++;                         // 更新正在使用的节点数量

    // 设置节点的 key 域
    dictSetKey(d, entry, key);

    return entry;   // 返回新节点
}
Beispiel #3
0
//这个函数也可以作为向外部提供的API使用,外部用户可以添加一个键值不为void*类型的值
//它向字典中添加一个key值并且返回新创建的 entry对象,这个对象交给调用者操作
dictEntry *dictAddRaw(dict *d, void *key)
{
    int index;
    dictEntry *entry;
    dictht *ht;

    if (dictIsRehashing(d)) _dictRehashStep(d);

    /* Get the index of the new element, or -1 if
     * the element already exists. */
    //获取对应key的bucket索引
    if ((index = _dictKeyIndex(d, key)) == -1)
        return NULL;

    /* Allocate the memory and store the new entry */
    //如果当前在执行rehash,说明需要将ht[0]上的entry转移到ht[1]上,并且尚未执行结束
    //这时候就需要加入到ht[1]中,否则加入到ht[0]中
    ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
    entry = zmalloc(sizeof(*entry));
    //加入到链表的表头
    entry->next = ht->table[index];
    ht->table[index] = entry;
    ht->used++;

    /* Set the hash entry fields. */
    //最后设置该项的key
    dictSetKey(d, entry, key);
    return entry;
}
Beispiel #4
0
/* Low level add. This function adds the entry but instead of setting
 * a value returns the dictEntry structure to the user, that will make
 * sure to fill the value field as he wishes.
 *
 * This function is also directly exposed to the user API to be called
 * mainly in order to store non-pointers inside the hash value, example:
 *
 * entry = dictAddRaw(dict,mykey);
 * if (entry != NULL) dictSetSignedIntegerVal(entry,1000);
 *
 * Return values:
 *
 * If key already exists NULL is returned.
 * If key was added, the hash entry is returned to be manipulated by the caller.
 */
dictEntry *dictAddRaw(dict *d, void *key)
{
    int index;
    dictEntry *entry;
    dictht *ht;

    if (dictIsRehashing(d)) _dictRehashStep(d);

    /* Get the index of the new element, or -1 if
     * the element already exists. */
    if ((index = _dictKeyIndex(d, key)) == -1)
        return NULL;

    /* Allocate the memory and store the new entry */
    ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0];
    entry = zmalloc(sizeof(*entry));
    entry->next = ht->table[index];
    ht->table[index] = entry;
    ht->used++;

    /* Set the hash entry fields. */
    //使用dictType中的keyDup函数
    dictSetKey(d, entry, key);
    return entry;
}
Beispiel #5
0
/* Add an element to the target hash table */
static int dictAdd(dict *ht, void *key, void *val) {
    int index;
    dictEntry *entry;

    /* Get the index of the new element, or -1 if
     * the element already exists. */
    if ((index = _dictKeyIndex(ht, key)) == -1)
        return DICT_ERR;

    /* Allocates the memory and stores key */
    entry = malloc(sizeof(*entry));
    entry->next = ht->table[index];
    ht->table[index] = entry;

    /* Set the hash entry fields. */
    dictSetHashKey(ht, entry, key);
    dictSetHashVal(ht, entry, val);
    ht->used++;
    return DICT_OK;
}