/** * Returns index for hash code h. */ staticintindexFor(int h, int length){ // 1 return h & (length-1); }
HashMap#hash()
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/** * Applies a supplemental hash function to a given hashCode, which * defends against poor quality hash functions. This is critical * because HashMap uses power-of-two length hash tables, that * otherwise encounter collisions for hashCodes that do not differ * in lower bits. Note: Null keys always map to hash 0, thus index 0. */ staticinthash(int h){ // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }
Redis2.4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
n.size = realsize; n.sizemask = realsize-1; .... hile(de) { unsignedint 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; }
/* Our hash table capability is a power of two */ staticunsignedlong _dictNextPower(unsignedlong size) { unsignedlong i = DICT_HT_INITIAL_SIZE; if (size >= LONG_MAX) return LONG_MAX; while(1) { if (i >= size) return i; i *= 2; } }
位运算的效率最高,这也是&取代%的原因。
例
1 2 3 4 5 6 7 8 9 10 11 12
intmain(int argc, char* argv[]) { int a = 0x111; int b = 0x222; int c = 0; int d = 0; c = a & (b-1); d = a % b; return0; }
反编译
1 2 3 4 5 6 7 8 9 10 11
13: c = a & (b-1); 00401044 mov eax,dword ptr [ebp-8] 00401047 sub eax,1 0040104A mov ecx,dword ptr [ebp-4] 0040104D and ecx,eax 0040104F mov dword ptr [ebp-0Ch],ecx 14: d = a % b; 00401052 mov eax,dword ptr [ebp-4] 00401055 cdq 00401056 idiv eax,dword ptr [ebp-8] 00401059 mov dword ptr [ebp-10h],edx