diff -urN linux-2.4.17-rc2-virgin/include/linux/pagemap.h linux-2.4.17-rc2-wli2/include/linux/pagemap.h --- linux-2.4.17-rc2-virgin/include/linux/pagemap.h Tue Dec 18 23:18:03 2001 +++ linux-2.4.17-rc2-wli2/include/linux/pagemap.h Thu Dec 20 18:55:30 2001 @@ -51,21 +51,17 @@ extern void page_cache_init(unsigned long); /* - * We use a power-of-two hash table to avoid a modulus, - * and get a reasonable hash by knowing roughly how the - * inode pointer and indexes are distributed (ie, we - * roughly know which bits are "significant") - * - * For the time being it will work for struct address_space too (most of - * them sitting inside the inodes). We might want to change it later. + * The multiplicative page cache hash from Chuck Lever's paper. + * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf + * page 3 describes the behavior of the different page cache hash + * functions. This could be painful without integer multiplies, so + * perhaps for wider portability conditional definitions would win. + * -- wli */ -static inline unsigned long _page_hashfn(struct address_space * mapping, unsigned long index) +static inline unsigned long _page_hashfn (struct address_space *mapping, unsigned long index) { -#define i (((unsigned long) mapping)/(sizeof(struct inode) & ~ (sizeof(struct inode) - 1))) -#define s(x) ((x)+((x)>>PAGE_HASH_BITS)) - return s(i+index) & (PAGE_HASH_SIZE-1); -#undef i -#undef s + return ((((unsigned long) mapping + index) * 2654435761UL) >> + (BITS_PER_LONG - PAGE_HASH_BITS)) & (PAGE_HASH_SIZE - 1); } #define page_hash(mapping,index) (page_hash_table+_page_hashfn(mapping,index))