示例#1
0
文件: dict.c 项目: AMCScarface/misc
/* Expand or create the hashtable */
int dictExpand(dict *d, unsigned long size)
{
    dictht n; /* the new hashtable */
    unsigned long realsize = _dictNextPower(size);

    /* the size is invalid if it is smaller than the number of
     * elements already inside the hashtable */
    if (dictIsRehashing(d) || d->ht[0].used > size)
        return DICT_ERR;

    /* Allocate the new hashtable and initialize all pointers to NULL */
    n.size = realsize;
    n.sizemask = realsize-1;
    n.table = zcalloc(1, realsize*sizeof(dictEntry*));
    n.used = 0;

    /* Is this the first initialization? If so it's not really a rehashing
     * we just set the first hash table so that it can accept keys. */
    if (d->ht[0].table == NULL) {
        d->ht[0] = n;
        return DICT_OK;
    }

    /* Prepare a second hash table for incremental rehashing */
    d->ht[1] = n;
    d->rehashidx = 0;
    return DICT_OK;
}
示例#2
0
//该函数会在真正创建哈希表或者扩展哈希表的时候被调用
int dictExpand(dict *d, unsigned long size)
{
    dictht n; /* the new hash table */
    //新的哈希表的bucket数目是大于当前used entry的数目的最小的2的指数
    unsigned long realsize = _dictNextPower(size);

    /* the size is invalid if it is smaller than the number of
     * elements already inside the hash table */
    //保证该字典未进行rehash,并且保证USED/BUCKETS的比率小于1
    if (dictIsRehashing(d) || d->ht[0].used > size)
        return DICT_ERR;

    /* Allocate the new hash table and initialize all pointers to NULL */
    //分配并初始化一个新的哈希表
    n.size = realsize;
    n.sizemask = realsize-1;
    n.table = zcalloc(realsize*sizeof(dictEntry*));
    n.used = 0;

    /* Is this the first initialization? If so it's not really a rehashing
     * we just set the first hash table so that it can accept keys. */
    //既然不是在rehash状态中,那么当前使用的哈希表应该是ht[0],如果它为NULL
    //说明这是在第一次分配该哈希表,所以将它保存在ht[0]中
    if (d->ht[0].table == NULL) {
        d->ht[0] = n;
        return DICT_OK;
    }

    /* Prepare a second hash table for incremental rehashing */
    //否则将新分配的哈希表保存在ht[1]中,因为不在rehash,所以当前ht[1]为空
    //并且标记rehash标志,在接下来的哈希表操作中会进行rehash操作
    d->ht[1] = n;
    d->rehashidx = 0;
    return DICT_OK;
}
示例#3
0
/* 对字典进行扩展
 *
 * 这个函数完成以下两个工作的其中之一:
 * 1) 如果字典的 0 号哈希表不存在,那么创建它
 * 2) 如果字典的 0 号哈希表存在,那么创建字典的 1 号哈希表
 *
 * 这个函数的作用,对于第一件任务来说,是创建字典(的哈希表)。
 * 而对于第二个任务来说,则是扩展字典(的哈希表)。
 */
int dictExpand(dict *d, unsigned long size)
{
    // 一般调用函数已经进行了检查,为了安全起见再次对参数进行检查
    if (dictIsRehashing(d) || d->ht[0].used > size)
        return DICT_ERR;

    // 计算哈希表的(真正)大小
    unsigned long realsize = _dictNextPower(size);

    // 创建新哈希表
    dictht n; 
    n.size = realsize;
    n.sizemask = realsize-1;
    n.table = zcalloc(realsize*sizeof(dictEntry*));
    n.used = 0;

    // 字典的 0 号哈希表是否已经初始化?
    // 如果没有的话,我们将新建哈希表作为字典的 0 号哈希表
    if (d->ht[0].table == NULL) {
        d->ht[0] = n;
    } else {
    // 否则,将新建哈希表作为字典的 1 号哈希表,并将它用于 rehash
        d->ht[1] = n;
        d->rehashidx = 0;
    }

    return DICT_OK;
}
示例#4
0
/* Expand or create the hashtable */
static int dictExpand(dict *ht, unsigned long size)
{
    dict n; /* the new hashtable */
    unsigned long realsize = _dictNextPower(size), i;

    /* the size is invalid if it is smaller than the number of
     * elements already inside the hashtable */
    if (ht->used > size)
        return DICT_ERR;

    _dictInit(&n, ht->type, ht->privdata);
    n.size = realsize;
    n.sizemask = realsize-1;
    n.table = calloc(realsize,sizeof(dictEntry*));

    /* Copy all the elements from the old to the new table:
     * note that if the old hash table is empty ht->size is zero,
     * so dictExpand just creates an hash table. */
    n.used = ht->used;
    for (i = 0; i < ht->size && ht->used > 0; i++) {
        dictEntry *he, *nextHe;

        if (ht->table[i] == NULL) continue;

        /* For each hash entry on this slot... */
        he = ht->table[i];
        while(he) {
            unsigned int h;

            nextHe = he->next;
            /* Get the new element index */
            h = dictHashKey(ht, he->key) & n.sizemask;
            he->next = n.table[h];
            n.table[h] = he;
            ht->used--;
            /* Pass to the next element */
            he = nextHe;
        }
    }
    assert(ht->used == 0);
    free(ht->table);

    /* Remap the new hashtable in the old */
    *ht = n;
    return DICT_OK;
}