Example #1
0
//添加or替换,如果key不存在就执行添加操作,返回1
//如果key存在更新value的值,返回0
int dictReplace(dict *d, void *key, void *val)
{
    dictEntry *entry, auxentry;

    /* Try to add the element. If the key
     * does not exists dictAdd will suceed. */
    //只有在这个key存在的情况下,才会返回DICT_ERR,所以如果返回为DICT_OK,
    //说明key不存在,并且添加成功.
    if (dictAdd(d, key, val) == DICT_OK)
        return 1;
    /* It already exists, get the entry */
    entry = dictFind(d, key);
    /* Set the new value and free the old one. Note that it is important
     * to do that in this order, as the value may just be exactly the same
     * as the previous one. In this context, think to reference counting,
     * you want to increment (set), and then decrement (free), and not the
     * reverse. */
    auxentry = *entry;
    //!!!这里有个疑问,这里说明必须首先设置然后再释放,但是执行了设置操作之后
    //该entry的值为新的value(可能是覆盖),接下来的释放操作如果将它free了呢?
    //也就是该哈希表的valDup函数为NULL,但是ValDestructor函数将free这个entry的value
    //那么这就编程了一个空悬指针!!!
    //有待加深理解。。。
    //既然作者的注释说明这样的顺序是防止两个value为同一个对象并且使用了引用计数,
    //如果这样可以简单的进行判断是否指向同一个对象,如果是直接返回
    //不知道我这样理解是否违反了作者的意图~~~
    dictSetVal(d, entry, val);
    dictFreeVal(d, &auxentry);
    return 0;
}
Example #2
0
/* 删除字典中指定的哈希表
 *
 * Destroy an entire dictionary
 *
 * Args:
 *  d 被删除的哈希表所属的字典
 *  ht 被删除的哈希表
 *
 * Returns:
 *  DICT_OK 删除成功(这个函数不可能失败)
 */
int _dictClear(dict *d, dictht *ht)
{
    unsigned long i;

    // 遍历整个哈希表,删除所有节点链
    /* Free all the elements */
    for (i = 0; i < ht->size && ht->used > 0; i++) {
        dictEntry *he, *nextHe;

        // 碰到空节点链,跳到下一个节点链去 
        if ((he = ht->table[i]) == NULL) continue;

        // 如果节点链非空,就遍历删除所有节点
        while(he) {
            nextHe = he->next;

            dictFreeKey(d, he); // 释放 key 空间
            dictFreeVal(d, he); // 释放 value 空间
            zfree(he);          // 释放节点

            ht->used--;         // 减少计数器

            he = nextHe;
        }
    }

    // 释放哈希表节点指针数组的空间
    /* Free the table and the allocated cache structure */
    zfree(ht->table);
    // 并重置(清空)哈希表各项属性
    /* Re-initialize the table */
    _dictReset(ht);

    return DICT_OK; /* never fails */
}
Example #3
0
/* Destroy an entire dictionary */
int _dictClear(dict *d, dictht *ht)
{
#ifdef _WIN32
    size_t i;
#else
    unsigned long i;
#endif

    /* Free all the elements */
    for (i = 0; i < ht->size && ht->used > 0; i++) {
        dictEntry *he, *nextHe;

        if ((he = ht->table[i]) == NULL) continue;
        while(he) {
            nextHe = he->next;
            dictFreeKey(d, he);
            dictFreeVal(d, he);
            zfree(he);
            ht->used--;
            he = nextHe;
        }
    }
    /* Free the table and the allocated cache structure */
    zfree(ht->table);
    /* Re-initialize the table */
    _dictReset(ht);
    return DICT_OK; /* never fails */
}
Example #4
0
/* 删除指定元素的底层实现代码
 *
 * Args:
 *  d
 *  key
 *  nofree 指示是否释放被删除元素的键和值
 *
 * Returns:
 *  DICT_ERR 字典为空,删除失败
 *  DICT_OK 删除成功
 */
static int dictGenericDelete(dict *d, const void *key, int nofree)
{
    unsigned int h, idx;
    dictEntry *he, *prevHe;
    int table;

    // 字典为空,删除失败
    if (d->ht[0].size == 0)
        return DICT_ERR;

    // 平摊 rehash
    if (dictIsRehashing(d))
        _dictRehashStep(d);

    // 哈希值
    h = dictHashKey(d, key);

    // 遍历
    for (table = 0; table <= 1; table++) {
        idx = h & d->ht[table].sizemask;    // 地址索引
        he = d->ht[table].table[idx];       // 表头节点
        prevHe = NULL;
        while(he) {
            if (dictCompareKeys(d, key, he->key)) {
                /* Unlink the element from the list */
                if (prevHe)
                    prevHe->next = he->next;
                else
                    d->ht[table].table[idx] = he->next;

                if (!nofree) {
                    dictFreeKey(d, he);
                    dictFreeVal(d, he);
                }

                zfree(he);
                d->ht[table].used--;

                return DICT_OK;
            }
            // 推进指针
            prevHe = he;
            he = he->next;
        }
        if (!dictIsRehashing(d)) break;
    }

    return DICT_ERR; /* not found */
}
Example #5
0
/* 将新元素添加到字典,如果 key 已经存在,那么新元素覆盖旧元素。
 *
 * Args:
 *  d 
 *  key 新元素的关键字
 *  val 新元素的值
 *
 * Return:
 *  1 key 不存在,新建元素添加成功
 *  0 key 已经存在,旧元素被新元素覆盖
 */
int dictReplace(dict *d, void *key, void *val)
{
    dictEntry *entry, auxentry;

    // 尝试添加元素,如果 key 不存在, 那么 dictAdd 完成工作
    if (dictAdd(d, key, val) == DICT_OK)
        return 1;

    // dictAdd 不成功,说明 key 已经存在
    // 找出这个元素并更新它的值
    entry = dictFind(d, key);
    auxentry = *entry;          // 用变量保存 entry 的引用
    dictSetVal(d, entry, val);  // 设置新值
    dictFreeVal(d, &auxentry);  // 释放旧值
    return 0;
}
Example #6
0
/* Add an element, discarding the old if the key already exists.
 * Return 1 if the key was added from scratch, 0 if there was already an
 * element with such key and dictReplace() just performed a value update
 * operation. */
int dictReplace(dict *d, void *key, void *val)
{
    dictEntry *entry, auxentry;

    /* Try to add the element. If the key
     * does not exists dictAdd will suceed. */
    if (dictAdd(d, key, val) == DICT_OK)
        return 1;
    /* It already exists, get the entry */
    entry = dictFind(d, key);
    /* Set the new value and free the old one. Note that it is important
     * to do that in this order, as the value may just be exactly the same
     * as the previous one. In this context, think to reference counting,
     * you want to increment (set), and then decrement (free), and not the
     * reverse. */
    auxentry = *entry;
    dictSetVal(d, entry, val);
    dictFreeVal(d, &auxentry);
    return 0;
}