e$B$J$+$@$G$9!#e(B
At Wed, 12 Mar 2008 19:50:18 +0900,
NARUSE, Yui wrote in [ruby-dev:34026]:
e$B$H$$$&$o$1$G!"e(Bint32_t, uint32_t, intptr_t, uintptr_t e$B$rDj5A$7$D$D!“e(B
hash() e$B$r%”%i%$%a%s%H9MN8$5$;$k%Q%C%A$G$9!#e(B
inttypes.he$B$r%A%'%C%/$7$F$J$$$h$&$J5$$,$7$^$9!#e(B
e$B$"$He(BBig
endiane$B$K$J$k$H$d$dCY$/$J$j$=$&$J$N$G!"0l1~:n$C$F$*$$$?$Ne(B
e$B$b=P$7$F$_$^$9!#e(B
Index: configure.in
— configure.in (revision 15758)
+++ configure.in (working copy)
@@ -583,5 +583,5 @@ AC_CHECK_HEADERS(stdlib.h string.h unist
syscall.h pwd.h grp.h a.out.h utime.h memory.h direct.h
sys/resource.h
sys/mkdev.h sys/utime.h xti.h netinet/in_systm.h float.h ieeefp.h
pthread.h \
dnl Check additional types.
@@ -621,4 +621,16 @@ AC_CHECK_TYPES(struct timespec)
AC_CHECK_TYPE(fd_mask, [AC_DEFINE(HAVE_RB_FD_INIT, 1)])
+test ${rb_cv_type_uint32_t+set} && ac_cv_type_uint32_t=yes
+AC_CHECK_TYPE(uint32_t)
+if test ${ac_cv_type_uint32_t} != yes; then
4]),
- [rb_cv_type_uint32_t=$type; break], [])
- done])
- AC_DEFINE(uint32_t, $rb_cv_type_uint32_t)
+fi
-
AC_CACHE_CHECK(for stack end address, rb_cv_stack_end_address,
[rb_cv_stack_end_address=no
Index: string.c
— string.c (revision 15758)
+++ string.c (working copy)
@@ -26,4 +26,8 @@
#endif
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
VALUE rb_cString;
VALUE rb_cSymbol;
@@ -1686,4 +1690,11 @@ rb_str_concat(VALUE str1, VALUE str2)
}
+#if defined i386 || defined _M_IX86 || defined __ia64
+#define UNALIGNED_WORD_ACCESS 1
+#endif
+#ifndef UNALIGNED_WORD_ACCESS
+#define UNALIGNED_WORD_ACCESS 0
+#endif
+
/* MurmurHash described in http://murmurhash.googlepages.com/ */
unsigned int
@@ -1695,14 +1706,93 @@ hash(const unsigned char * data, int len
h += 0xdeadbeef;
- while(len >= 4) {
- h += *(unsigned int *)data;
- h *= m;
- h ^= h >> r;
- if (len >= 4) {
+#if !UNALIGNED_WORD_ACCESS
- int align = (VALUE)data & 3;
- if (align) {
-
uint32_t t = 0, d = 0;
-
int sl, sr, pack;
-
-
switch (align) {
+#ifdef WORDS_BIGENDIAN
+#else
+#endif
+#ifdef WORDS_BIGENDIAN
-
case 3: d |= data[2];
-
case 2: d |= data[1] << 8;
-
case 1: d |= data[0] << 16;
-
case 0:
- h += (t << sr) | (d >> sl);
+#else
-
case 3: d |= data[2] << 16;
-
case 2: d |= data[1] << 8;
-
case 1: d |= data[0];
-
case 0:
- h += (t >> sr) | (d << sl);
+#endif
- h *= m;
- h ^= h >> r;
-
}
-
data += pack;
-
len -= pack;
-
}
-
else
+#endif
-
{
-
do {
-
h += *(uint32_t *)data;
-
h *= m;
-
h ^= h >> r;
-
-
data += 4;
-
len -= 4;
-
} while (len >= 4);
-
}
}
switch(len) {
+#ifdef WORDS_BIGENDIAN
-
case 3:
-
h += data[2];
-
case 2:
-
h += data[1] << 8;
-
case 1:
-
h += data[0] << 16;
+#else
case 3:
h += data[2] << 16;
@@ -1711,4 +1801,5 @@ hash(const unsigned char * data, int len
case 1:
h += data[0];
+#endif
h *= m;
h ^= h >> r;