null+****@clear*****
null+****@clear*****
2010年 6月 30日 (水) 14:20:26 JST
Daijiro MORI 2010-06-30 05:20:26 +0000 (Wed, 30 Jun 2010) New Revision: b5581a97604e73c454e7fc2967bea24112aa7c31 Log: Added GRN_OBJ_KEY_GEO_POINT. Modified files: groonga.h lib/db.c lib/pat.c Modified: groonga.h (+1 -0) =================================================================== --- groonga.h 2010-06-29 14:10:52 +0000 (c60582c) +++ groonga.h 2010-06-30 05:20:26 +0000 (04c35c5) @@ -252,6 +252,7 @@ typedef unsigned short int grn_obj_flags; #define GRN_OBJ_KEY_UINT (0x00<<3) #define GRN_OBJ_KEY_INT (0x01<<3) #define GRN_OBJ_KEY_FLOAT (0x02<<3) +#define GRN_OBJ_KEY_GEO_POINT (0x03<<3) #define GRN_OBJ_KEY_WITH_SIS (0x01<<6) #define GRN_OBJ_KEY_NORMALIZE (0x01<<7) Modified: lib/db.c (+3 -2) =================================================================== --- lib/db.c 2010-06-29 14:10:52 +0000 (5b4ca2c) +++ lib/db.c 2010-06-30 05:20:26 +0000 (3cf15d9) @@ -6452,6 +6452,7 @@ grn_table_sort(grn_ctx *ctx, grn_obj *table, int offset, int limit, uint8_t key_type = range->header.flags & GRN_OBJ_KEY_MASK; switch (key_type) { case GRN_OBJ_KEY_UINT : + case GRN_OBJ_KEY_GEO_POINT : switch (GRN_TYPE_SIZE(DB_OBJ(range))) { case 1 : kp->offset = KEY_UINT8; @@ -6594,10 +6595,10 @@ grn_db_init_builtin_types(grn_ctx *ctx) GRN_OBJ_KEY_VAR_SIZE, 1 << 31); if (!obj || DB_OBJ(obj)->id != GRN_DB_LONG_TEXT) { return GRN_FILE_CORRUPT; } obj = deftype(ctx, "TokyoGeoPoint", - GRN_OBJ_KEY_UINT, sizeof(grn_geo_point)); + GRN_OBJ_KEY_GEO_POINT, sizeof(grn_geo_point)); if (!obj || DB_OBJ(obj)->id != GRN_DB_TOKYO_GEO_POINT) { return GRN_FILE_CORRUPT; } obj = deftype(ctx, "WGS84GeoPoint", - GRN_OBJ_KEY_UINT, sizeof(grn_geo_point)); + GRN_OBJ_KEY_GEO_POINT, sizeof(grn_geo_point)); if (!obj || DB_OBJ(obj)->id != GRN_DB_WGS84_GEO_POINT) { return GRN_FILE_CORRUPT; } for (id = grn_pat_curr_id(ctx, ((grn_db *)db)->keys) + 1; id < GRN_DB_MECAB; id++) { grn_itoh(id, buf + 3, 2); Modified: lib/pat.c (+48 -2) =================================================================== --- lib/pat.c 2010-06-29 14:10:52 +0000 (5080f24) +++ lib/pat.c 2010-06-30 05:20:26 +0000 (ac8e233) @@ -647,6 +647,40 @@ chop(grn_ctx *ctx, grn_pat *pat, const char **key, const char *end, uint32_t *lk } } +static void +grn_gton(uint8_t *keybuf, const void *key, uint32_t size) +{ + 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)); + } +} + +static void +grn_ntog(uint8_t *keybuf, uint8_t *key, uint32_t 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; +} + #define MAX_FIXED_KEY_SIZE (sizeof(int64_t)) #define KEY_NEEDS_CONVERT(pat,size) \ @@ -655,7 +689,13 @@ chop(grn_ctx *ctx, grn_pat *pat, const char **key, const char *end, uint32_t *lk #define KEY_ENC(pat,keybuf,key,size) {\ switch ((pat)->obj.header.flags & GRN_OBJ_KEY_MASK) {\ case GRN_OBJ_KEY_UINT :\ - grn_hton((keybuf), (key), (size));\ + if (((pat)->obj.header.domain != GRN_DB_TOKYO_GEO_POINT) &&\ + ((pat)->obj.header.domain != GRN_DB_WGS84_GEO_POINT)) {\ + grn_hton((keybuf), (key), (size));\ + break;\ + }\ + case GRN_OBJ_KEY_GEO_POINT :\ + grn_gton((keybuf), (key), (size));\ break;\ case GRN_OBJ_KEY_INT :\ grn_hton((keybuf), (key), (size));\ @@ -674,7 +714,13 @@ chop(grn_ctx *ctx, grn_pat *pat, const char **key, const char *end, uint32_t *lk #define KEY_DEC(pat,keybuf,key,size) {\ switch ((pat)->obj.header.flags & GRN_OBJ_KEY_MASK) {\ case GRN_OBJ_KEY_UINT :\ - grn_ntoh((keybuf), (key), (size));\ + if (((pat)->obj.header.domain != GRN_DB_TOKYO_GEO_POINT) &&\ + ((pat)->obj.header.domain != GRN_DB_WGS84_GEO_POINT)) {\ + grn_ntoh((keybuf), (key), (size));\ + break;\ + }\ + case GRN_OBJ_KEY_GEO_POINT :\ + grn_ntog((keybuf), (key), (size));\ break;\ case GRN_OBJ_KEY_INT :\ grn_ntohi((keybuf), (key), (size));\