REDIS源碼中一些值得學習的技術細節02

來源:互聯網
上載者:User

標籤:

1. Redis中散列函數的實現:

Redis針對整數key和字串key,採用了不同的散列函數

對於整數key,redis使用了 Thomas Wang的 32 bit Mix Function,實現了dict.c/dictIntHashFunction函數:

 1 /* Thomas Wang‘s 32 bit Mix Function */ 2 unsigned int dictIntHashFunction(unsigned int key) 3 { 4     key += ~(key << 15); 5     key ^=  (key >> 10); 6     key +=  (key << 3); 7     key ^=  (key >> 6); 8     key += ~(key << 11); 9     key ^=  (key >> 16);10     return key;11 }

這段代碼的妙處我還沒來得及仔細研究,等研究好了會在這裡補上,不過找到了兩個初看還不錯的連結:

首先是Thomas Wang大神本人的連結:

http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm

再者是他人根據上面連結和其他資料寫的總結

http://blog.csdn.net/jasper_xulei/article/details/18364313

 

對於字串形式的key,redis使用了MurmurHash2演算法和djb演算法:

MurmurHash2演算法對於key是大小寫敏感的,而且在大端機器和小端機器上產生結果不一致

redis的dict.c/dictGenHashFunction是MurmurHash2演算法的C語言實現:

 1 unsigned int dictGenHashFunction(const void *key, int len) { 2     /* ‘m‘ and ‘r‘ are mixing constants generated offline. 3      They‘re not really ‘magic‘, they just happen to work well.  */ 4     uint32_t seed = dict_hash_function_seed; 5     const uint32_t m = 0x5bd1e995; 6     const int r = 24; 7  8     /* Initialize the hash to a ‘random‘ value */ 9     uint32_t h = seed ^ len;10 11     /* Mix 4 bytes at a time into the hash */12     const unsigned char *data = (const unsigned char *)key;13 14     while(len >= 4) {15         uint32_t k = *(uint32_t*)data;16 17         k *= m;18         k ^= k >> r;19         k *= m;20 21         h *= m;22         h ^= k;23 24         data += 4;25         len -= 4;26     }27 28     /* Handle the last few bytes of the input array  */29     switch(len) {30     case 3: h ^= data[2] << 16;31     case 2: h ^= data[1] << 8;32     case 1: h ^= data[0]; h *= m;33     };34 35     /* Do a few final mixes of the hash to ensure the last few36      * bytes are well-incorporated. */37     h ^= h >> 13;38     h *= m;39     h ^= h >> 15;40 41     return (unsigned int)h;42 }

而redis則藉助djb函數實現了不區分大小寫散列函數dict.c/dictGenCaseHashFunction:

1 unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {2     unsigned int hash = (unsigned int)dict_hash_function_seed;3 4     while (len--)5         hash = ((hash << 5) + hash) + (tolower(*buf++)); /* hash * 33 + c */6     return hash;7 }

以上三個散列函數(dictIntHashFunction, dictIntHashFunction, dictGenCaseHashFunction)分別用在了redis的不同地方,用以實現了不同場合下的散列需求,接下來將會詳細介紹。

 

2.Redis中不同場合下幾種不同散列函數的使用

 

REDIS源碼中一些值得學習的技術細節02

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.