flashcache之hash_block

dmc->size表示flashcache中block的数目,而在flashcache_ctr中:
    dmc->assoc_shift = ffs(dmc->assoc) - 1;
因为dmc->assoc表示一个set中块的数目,那么dmc->assoc_shift则表示dmc->assoc二进制形式中0的个数。这样可以使用位运算加快除法速度。也就是说: num_cache_sets = dmc->size >> dmc->assoc_shift;是flashcache中的set数目。
因为我使用的版本是flashcache 3.1.1,所以来看else子句
    value = (unsigned long) (dbn >> dmc->disk_assoc_shift);
    /* Then place it in a random set */
    value = jhash_1word(value, 0xbeef);
这里的value = (unsigned long) (dbn >> dmc->disk_assoc_shift);相当于
value = (unsigned long) (dbn / dmc->disk_assoc);所以来看看jhash_1word做了啥:
170 static inline u32 jhash_1word(u32 a, u32 initval)
171 {
172         return __jhash_nwords(a, 0, 0, initval + JHASH_INITVAL + (1 << 2));
173 }
其中调用了__jhash_nwords(value, 0, 0, 0xbeef + JHASH_INITVAL + (1 << 2)); 其中JHASH_INITVAL被初始化为任意值:
 57 /* An arbitrary initial parameter */
 58 #define JHASH_INITVAL 0xdeadbeef
而在__jhash_nwords函数中,
149 static inline u32 __jhash_nwords(u32 a, u32 b, u32 c, u32 initval)
150 {
151         a += initval;
152         b += initval;
153         c += initval;
154 
155         __jhash_final(a, b, c);
156 
157         return c;
158 }
又调用了 __jhash_final(value+initval, initval, initval); 在该函数中,进行了奇怪的运算:
 45 /* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
 46 #define __jhash_final(a, b, c) \
 47 {                                               \
 48         c ^= b; c -= rol32(b, 14);              \
 49         a ^= c; a -= rol32(c, 11);              \
 50         b ^= a; b -= rol32(a, 25);              \
 51         c ^= b; c -= rol32(b, 16);              \
 52         a ^= c; a -= rol32(c, 4);               \
 53         b ^= a; b -= rol32(a, 14);              \
 54         c ^= b; c -= rol32(b, 24);              \
 55 }
好吧,来看看rol32函数,应该是不会用到随机函数,不然以后每次相同的dbn找的cache block岂不是不相同:
103 /** 104 * rol32 - rotate a 32-bit value left 105 * @word: value to rotate 106 * @shift: bits to roll 107 */
108 static inline __u32 rol32(__u32 word, unsigned int shift)
109 {
110         return (word << shift) | (word >> ((-shift) & 31));
111 }
112 
113 /**
果然不是什么随机函数,只是一些位运算罢了,从这里可以印证出每次相同的dbn找的cache block是相同的。
注意hash_block末尾的这句话set_number = value % num_cache_sets; 加上前面的value = (unsigned long) (dbn >> dmc->disk_assoc_shift);印证了flashcache-doc.txt的这句话: 
target set = (dbn / block size / set size) mod (number of sets),但是好像这句话有点老,因为在if语句里面才是完全符合这句话:value = (unsigned long)
        (dbn >> (dmc->block_shift + dmc->assoc_shift));

你可能感兴趣的:(c,flashcache)