Esempio n. 1
0
/* Initialize the hash table */
int _dictInit(dict *d, dictType *type,
        void *privDataPtr)
{
    _dictReset(&d->ht[0]);
    _dictReset(&d->ht[1]);
    d->type = type;
    d->privdata = privDataPtr;
    d->rehashidx = -1;
    d->iterators = 0;
    return DICT_OK;
}
Esempio n. 2
0
/* 初始化字典 */
int _dictInit(dict *d, dictType *type, void *privDataPtr)
{
    _dictReset(&d->ht[0]);      // 初始化字典内的两个哈希表
    _dictReset(&d->ht[1]);

    d->type = type;             // 设置函数指针
    d->privdata = privDataPtr; 
    d->rehashidx = -1;          // -1 表示没有在进行 rehash
    d->iterators = 0;           // 0 表示没有迭代器在进行迭代

    return DICT_OK;             // 返回成功信号
}
Esempio n. 3
0
/* Initialize the hash table */
static int _dictInit(dict *ht, dictType *type, void *privDataPtr)
{
    _dictReset(ht);
    ht->type = type;
    ht->privdata = privDataPtr;
    return DICT_OK;
}
Esempio n. 4
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 */
}
Esempio n. 5
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;
            dictFreeEntryKey(d, he);
            dictFreeEntryVal(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 */
}
Esempio n. 6
0
/* 字典(的哈希表) rehash 函数
 *
 * Args:
 *  d
 *  n 要执行 rehash 的元素数量
 *
 * Returns:
 *  0 所有元素 rehash 完毕
 *  1 还有元素没有 rehash
 */
int dictRehash(dict *d, int n) {
    if (!dictIsRehashing(d))
        return 0;

    while(n--) {
        dictEntry *de, *nextde;

        // 0 号哈希表的所有元素 rehash 完毕?
        if (d->ht[0].used == 0) {
            zfree(d->ht[0].table);  // 替换 1 号为 0 号
            d->ht[0] = d->ht[1];

            _dictReset(&d->ht[1]);  // 重置 1 号哈希表

            d->rehashidx = -1;      // 重置 rehash flag

            return 0;
        }

        /* Note that rehashidx can't overflow as we are sure there are more
         * elements because ht[0].used != 0 */
        assert(d->ht[0].size > (unsigned)d->rehashidx);

        // 略过所有空链
        while(d->ht[0].table[d->rehashidx] == NULL)
            d->rehashidx++;

        // 指向链头
        de = d->ht[0].table[d->rehashidx];
        // 将链表内的所有节点移动到 1 号哈希表
        while(de) {
            unsigned int h;

            nextde = de->next;

            // 计算新的地址(用于 1 号哈希表)
            h = dictHashKey(d, de->key) & d->ht[1].sizemask;

            de->next = d->ht[1].table[h];   // 更新 next 指针
            d->ht[1].table[h] = de;         // 移动
            d->ht[0].used--;                // 更新 0 号表计算器
            d->ht[1].used++;                // 更新 1 号表计算器

            de = nextde;
        }

        d->ht[0].table[d->rehashidx] = NULL;    // 清空链头
        d->rehashidx++; // 更新索引
    }

    return 1;
}
Esempio n. 7
0
//执行一次rehash操作,一般在检查到该字典的rehash标记被设置之后调用该函数
//这里的参数n表示至少执行多少bucket的移动(reahash),每次移动从rehashidx开始
int dictRehash(dict *d, int n) {
    if (!dictIsRehashing(d)) return 0;

    while(n--) {
        dictEntry *de, *nextde;

        /* Check if we already rehashed the whole table... */
        //如果已经全部移动了,说明这一次rehash操作执行完成了
        //释放ht[0],然后重新将移动之后的ht[1]替换,这样保证不再rehash操作
        //的时候都是使用ht[0]保存新添加的元素
        if (d->ht[0].used == 0) {
            zfree(d->ht[0].table);
            //复制&重置
            d->ht[0] = d->ht[1];
            _dictReset(&d->ht[1]);
            d->rehashidx = -1;
            return 0;
        }

        /* Note that rehashidx can't overflow as we are sure there are more
         * elements because ht[0].used != 0 */
        //在rehash过程中,rehashidx保存的是上一次移动的bucket的下标
        //这样在下一次移动的时候从rehashidx开始
        assert(d->ht[0].size > (unsigned)d->rehashidx);
        //跳过没有任何元素的bucket
        while(d->ht[0].table[d->rehashidx] == NULL) d->rehashidx++;
        de = d->ht[0].table[d->rehashidx];
        /* Move all the keys in this bucket from the old to the new hash HT */
        //将旧哈希表ht[0]中的每一个bucket上的每一个entry都移动到ht[1]上
        //因为同一个entry在两个表定位的bucket不同,所以需要重新hash,然后添加到bucket
        //中entry链表的表头
        while(de) {
            unsigned int h;

            nextde = de->next;
            /* Get the index in the new hash table */
            h = dictHashKey(d, de->key) & d->ht[1].sizemask;
            de->next = d->ht[1].table[h];
            d->ht[1].table[h] = de;
            d->ht[0].used--;
            d->ht[1].used++;
            de = nextde;
        }
        d->ht[0].table[d->rehashidx] = NULL;
        d->rehashidx++;
    }
    return 1;
}
Esempio n. 8
0
/* Performs N steps of incremental rehashing. Returns 1 if there are still
 * keys to move from the old to the new hash table, otherwise 0 is returned.
 * Note that a rehashing step consists in moving a bucket (that may have more
 * thank one key as we use chaining) from the old to the new hash table. */
int dictRehash(dict *d, int n) {
    if (!dictIsRehashing(d)) return 0;

    while(n--) {
        dictEntry *de, *nextde;

        /* Check if we already rehashed the whole table... */
        if (d->ht[0].used == 0) {
            free(d->ht[0].table);
            d->ht[0] = d->ht[1];
            _dictReset(&d->ht[1]);
            d->rehashidx = -1;
            return 0;
        }

        /* Note that rehashidx can't overflow as we are sure there are more
         * elements because ht[0].used != 0 */
        assert(d->ht[0].size > (unsigned)d->rehashidx);
        while(d->ht[0].table[d->rehashidx] == NULL) d->rehashidx++;
        de = d->ht[0].table[d->rehashidx];
        /* Move all the keys in this bucket from the old to the new hash HT */
        while(de) {
            unsigned int h;

            nextde = de->next;
            /* Get the index in the new hash table */
            h = dictHashKey(d, de->key) & d->ht[1].sizemask;
            de->next = d->ht[1].table[h];
            d->ht[1].table[h] = de;
            d->ht[0].used--;
            d->ht[1].used++;
            de = nextde;
        }
        d->ht[0].table[d->rehashidx] = NULL;
        d->rehashidx++;
    }
    return 1;
}
Esempio n. 9
0
File: dict.c Progetto: snoplus/orca
/* Destroy an entire hash table */
static int _dictClear(dict *ht) {
    uint32_t 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;
            dictFreeEntryKey(ht, he);
            dictFreeEntryVal(ht, he);
            free(he);
            ht->used--;
            he = nextHe;
        }
    }
    /* Free the table and the allocated cache structure */
    free(ht->table);
    /* Re-initialize the table */
    _dictReset(ht);
    return DICT_OK; /* never fails */
}