1. 程式人生 > >Memcached原始碼分析之Hash表操作

Memcached原始碼分析之Hash表操作

Memcached的Hash表用來提高資料訪問效能,通過連結法來解決Hash衝突,當Hash表中資料多餘Hash表容量的1.5倍時,Hash表就會擴容,Memcached的Hash表操作沒什麼特別的,我們這裡簡單介紹下Memcached裡面的Hash表操作。

//hash表插入元素
int assoc_insert(item *it, const uint32_t hv) {
    unsigned int oldbucket;

    if (expanding &&
        (oldbucket = (hv & hashmask(hashpower - 1))) >= expand_bucket)//如果已經開始擴容,且擴容的桶編號大於目前的item所在桶的編號
    {
        it->h_next = old_hashtable[oldbucket];//這裡是類似單鏈表的,按單鏈表的操作進行插入
        old_hashtable[oldbucket] = it;
    } else {//已經擴容,則按新的Hash規則進行路由
        it->h_next = primary_hashtable[hv & hashmask(hashpower)];//這裡在新的Hash表中執行單鏈表插入
        primary_hashtable[hv & hashmask(hashpower)] = it;
    }

    hash_items++;//元素個數+1
    if (! expanding && hash_items > (hashsize(hashpower) * 3) / 2) {//開始擴容
        assoc_start_expand();//喚醒擴容條件變數
    }

    MEMCACHED_ASSOC_INSERT(ITEM_key(it), it->nkey, hash_items);
    return 1;
}
//hash表刪除元素
void assoc_delete(const char *key, const size_t nkey, const uint32_t hv) {
    item **before = _hashitem_before(key, nkey, hv);//獲得item對應的桶的前一個元素

    if (*before) {
        item *nxt;
        hash_items--;//元素個數-1
        MEMCACHED_ASSOC_DELETE(key, nkey, hash_items);
        nxt = (*before)->h_next;//執行單鏈表的刪除操作
        (*before)->h_next = 0;
        *before = nxt;
        return;
    }
    assert(*before != 0);
}
像Hash表的擴容,初始化等已經在其他部落格中介紹過了,這裡就不在闡述。