[Groonga-commit] groonga/groonga [master] Improve grn_gton() and grn_ntog() for faster geo-location search.

Back to archive index

susumu.yata null+****@clear*****
Tue Apr 2 19:03:25 JST 2013


susumu.yata	2013-04-02 19:03:25 +0900 (Tue, 02 Apr 2013)

  New Revision: f62fb0729ba0f89003b190f8d0d3049a863fe8af
  https://github.com/groonga/groonga/commit/f62fb0729ba0f89003b190f8d0d3049a863fe8af

  Message:
    Improve grn_gton() and grn_ntog() for faster geo-location search.

  Modified files:
    lib/groonga_in.h

  Modified: lib/groonga_in.h (+62 -29)
===================================================================
--- lib/groonga_in.h    2013-04-02 16:28:15 +0900 (2ebb154)
+++ lib/groonga_in.h    2013-04-02 19:03:25 +0900 (82900e8)
@@ -603,39 +603,72 @@ grn_str_greater(const uint8_t *ap, uint32_t as, const uint8_t *bp, uint32_t bs)
 #endif /* WORDS_BIGENDIAN */
 #define grn_ntoh(buf,key,size) grn_hton(buf,key,size)
 
+#ifdef _MSC_VER
+# define grn_bswap_uint64(in, out) ((out) = _byteswap_uint64(in))
+#else /* _MSC_VER */
+# ifdef __GNUC__
+#  define grn_bswap_uint64(in, out) ((out) = __builtin_bswap64(in))
+# else /* __GNUC__ */
+#  define grn_bswap_uint64(in, out) do {\
+  uint64_t temp_ = (in);\
+  (out) = (temp_ << 56) |\
+          ((temp_ & (0xFFULL << 8)) << 40) |\
+          ((temp_ & (0xFFULL << 16)) << 24) |\
+          ((temp_ & (0xFFULL << 24)) << 8) |\
+          ((temp_ & (0xFFULL << 32)) >> 8) |\
+          ((temp_ & (0xFFULL << 40)) >> 24) |\
+          ((temp_ & (0xFFULL << 48)) >> 40) |\
+          (temp_ >> 56);\
+} while (0)
+# endif /* __GNUC__ */
+#endif /* _MSC_VER */
+
+#ifdef WORDS_BIGENDIAN
+# define grn_hton_uint64(in, out) ((out) = (in))
+#else /* WORDS_BIGENDIAN */
+# define grn_hton_uint64(in, out) grn_bswap_uint64(in, out)
+#endif /* WORDS_BIGENDIAN */
+#define grn_ntoh_uint64(in, out) grn_hton_uint64(in, out)
+
 #define grn_gton(keybuf,key,size) do {\
-  uint8_t *keybuf_ = keybuf;\
-  const void *key_ = key;\
-  int la = ((grn_geo_point *)key_)->latitude;\
-  int lo = ((grn_geo_point *)key_)->longitude;\
-  uint8_t *p = keybuf_;\
-  int i = 32;\
-  while (i) {\
-    i -= 4;\
-    *p++ = ((((la >> i) & 8) << 4) + (((lo >> i) & 8) << 3) +\
-            (((la >> i) & 4) << 3) + (((lo >> i) & 4) << 2) +\
-            (((la >> i) & 2) << 2) + (((lo >> i) & 2) << 1) +\
-            (((la >> i) & 1) << 1) + (((lo >> i) & 1) << 0));\
-  }\
+  const grn_geo_point *point_ = (const grn_geo_point *)key;\
+  uint64_t la_ = (uint32_t)point_->latitude;\
+  uint64_t lo_ = (uint32_t)point_->longitude;\
+  uint64_t result_;\
+  la_ = (la_ | (la_ << 16)) & 0x0000FFFF0000FFFFULL;\
+  la_ = (la_ | (la_ <<  8)) & 0x00FF00FF00FF00FFULL;\
+  la_ = (la_ | (la_ <<  4)) & 0x0F0F0F0F0F0F0F0FULL;\
+  la_ = (la_ | (la_ <<  2)) & 0x3333333333333333ULL;\
+  la_ = (la_ | (la_ <<  1)) & 0x5555555555555555ULL;\
+  lo_ = (lo_ | (lo_ << 16)) & 0x0000FFFF0000FFFFULL;\
+  lo_ = (lo_ | (lo_ <<  8)) & 0x00FF00FF00FF00FFULL;\
+  lo_ = (lo_ | (lo_ <<  4)) & 0x0F0F0F0F0F0F0F0FULL;\
+  lo_ = (lo_ | (lo_ <<  2)) & 0x3333333333333333ULL;\
+  lo_ = (lo_ | (lo_ <<  1)) & 0x5555555555555555ULL;\
+  result_ = (la_ << 1) | lo_;\
+  grn_hton_uint64(result_, result_);\
+  memcpy(keybuf, &result_, sizeof(result_));\
 } while (0)
 
 #define grn_ntog(keybuf,key,size) do {\
-  uint8_t *keybuf_ = keybuf;\
-  uint8_t *key_ = key;\
-  uint32_t size_ = size;\
-  int la = 0, lo = 0;\
-  uint8_t v, *p = key_;\
-  int i = 32;\
-  while (size_--) {\
-    i -= 4;\
-    v = *p++;\
-    la += (((v & 128) >> 4) + ((v &  32) >> 3) +\
-           ((v &   8) >> 2) + ((v &   2) >> 1)) << i;\
-    lo += (((v &  64) >> 3) + ((v &  16) >> 2) +\
-           ((v &   4) >> 1) + ((v &   1) >> 0)) << i;\
-  }\
-  ((grn_geo_point *)keybuf_)->latitude = la;\
-  ((grn_geo_point *)keybuf_)->longitude = lo;\
+  grn_geo_point *point_ = (grn_geo_point *)keybuf;\
+  uint64_t key_ = *(const uint64_t *)key;\
+  uint64_t la_, lo_;\
+  grn_ntoh_uint64(key_, key_);\
+  la_ = (key_ >> 1) & 0x5555555555555555ULL;\
+  lo_ = key_ & 0x5555555555555555ULL;\
+  la_ = (la_ | (la_ >>  1)) & 0x3333333333333333ULL;\
+  la_ = (la_ | (la_ >>  2)) & 0x0F0F0F0F0F0F0F0FULL;\
+  la_ = (la_ | (la_ >>  4)) & 0x00FF00FF00FF00FFULL;\
+  la_ = (la_ | (la_ >>  8)) & 0x0000FFFF0000FFFFULL;\
+  la_ = (la_ | (la_ >> 16)) & 0x00000000FFFFFFFFULL;\
+  lo_ = (lo_ | (lo_ >>  1)) & 0x3333333333333333ULL;\
+  lo_ = (lo_ | (lo_ >>  2)) & 0x0F0F0F0F0F0F0F0FULL;\
+  lo_ = (lo_ | (lo_ >>  4)) & 0x00FF00FF00FF00FFULL;\
+  lo_ = (lo_ | (lo_ >>  8)) & 0x0000FFFF0000FFFFULL;\
+  lo_ = (lo_ | (lo_ >> 16)) & 0x00000000FFFFFFFFULL;\
+  point_->latitude = la_;\
+  point_->longitude = lo_;\
 } while (0)
 
 #ifndef HAVE_STRTOULL
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index