null+****@clear*****
null+****@clear*****
2011年 11月 18日 (金) 15:30:03 JST
Kouhei Sutou 2011-11-18 06:30:03 +0000 (Fri, 18 Nov 2011)
New Revision: bf90e2b328bb0e030d9ed741e87f461a8ba96331
Log:
[geo] fix initial cursor key. refs #1173
Modified files:
lib/geo.c
Modified: lib/geo.c (+47 -26)
===================================================================
--- lib/geo.c 2011-11-18 05:26:13 +0000 (450a502)
+++ lib/geo.c 2011-11-18 06:30:03 +0000 (f478e2e)
@@ -46,8 +46,9 @@ typedef struct {
int end;
int distance;
int diff_bit;
- int rectangle_common_bit;
grn_geo_mesh_direction direction;
+ int rectangle_common_bit;
+ uint8_t rectangle_common_key[sizeof(grn_geo_point)];
} in_rectangle_data;
static int
@@ -72,35 +73,52 @@ compute_diff_bit(uint8_t *geo_key1, uint8_t *geo_key2)
}
static void
-compute_min_and_max(grn_geo_point *base_point, int diff_bit,
- grn_geo_point *geo_min, grn_geo_point *geo_max)
+compute_min_and_max_key(uint8_t *key_base, int diff_bit,
+ uint8_t *key_min, uint8_t *key_max)
{
int diff_byte, diff_bit_mask;
- uint8_t geo_key_base[sizeof(grn_geo_point)];
- uint8_t geo_key_min[sizeof(grn_geo_point)];
- uint8_t geo_key_max[sizeof(grn_geo_point)];
diff_byte = diff_bit / 8;
diff_bit_mask = 0xff >> (diff_bit % 8);
- grn_gton(geo_key_base, base_point, sizeof(grn_geo_point));
if (diff_byte == sizeof(grn_geo_point)) {
- memcpy(geo_key_min, geo_key_base, diff_byte);
- memcpy(geo_key_max, geo_key_base, diff_byte);
+ if (key_min) { memcpy(key_min, key_base, diff_byte); }
+ if (key_max) { memcpy(key_max, key_base, diff_byte); }
} else {
- memcpy(geo_key_min, geo_key_base, diff_byte + 1);
- geo_key_min[diff_byte] &= ~diff_bit_mask;
- memset(geo_key_min + diff_byte + 1, 0,
- sizeof(grn_geo_point) - diff_byte - 1);
-
- memcpy(geo_key_max, geo_key_base, diff_byte + 1);
- geo_key_max[diff_byte] |= diff_bit_mask;
- memset(geo_key_max + diff_byte + 1, 0xff,
- sizeof(grn_geo_point) - diff_byte - 1);
+ if (key_min) {
+ memcpy(key_min, key_base, diff_byte + 1);
+ key_min[diff_byte] &= ~diff_bit_mask;
+ memset(key_min + diff_byte + 1, 0,
+ sizeof(grn_geo_point) - diff_byte - 1);
+ }
+
+ if (key_max) {
+ memcpy(key_max, key_base, diff_byte + 1);
+ key_max[diff_byte] |= diff_bit_mask;
+ memset(key_max + diff_byte + 1, 0xff,
+ sizeof(grn_geo_point) - diff_byte - 1);
+ }
}
+}
+
+static void
+compute_min_and_max(grn_geo_point *base_point, int diff_bit,
+ grn_geo_point *geo_min, grn_geo_point *geo_max)
+{
+ uint8_t geo_key_base[sizeof(grn_geo_point)];
+ uint8_t geo_key_min[sizeof(grn_geo_point)];
+ uint8_t geo_key_max[sizeof(grn_geo_point)];
- grn_ntog((uint8_t *)geo_min, geo_key_min, sizeof(grn_geo_point));
- grn_ntog((uint8_t *)geo_max, geo_key_max, sizeof(grn_geo_point));
+ grn_gton(geo_key_base, base_point, sizeof(grn_geo_point));
+ compute_min_and_max_key(geo_key_base, diff_bit,
+ geo_min ? geo_key_min : NULL,
+ geo_max ? geo_key_max : NULL);
+ if (geo_min) {
+ grn_ntog((uint8_t *)geo_min, geo_key_min, sizeof(grn_geo_point));
+ }
+ if (geo_max) {
+ grn_ntog((uint8_t *)geo_max, geo_key_max, sizeof(grn_geo_point));
+ }
}
/* #define GEO_DEBUG */
@@ -944,12 +962,16 @@ in_rectangle_data_prepare(grn_ctx *ctx, grn_obj *index,
grn_gton(geo_key_input, geo_point_input, sizeof(grn_geo_point));
grn_gton(geo_key_base, &(data->base), sizeof(grn_geo_point));
data->diff_bit = compute_diff_bit(geo_key_input, geo_key_base);
+ compute_min_and_max(&(data->base), data->diff_bit,
+ &(data->min), &(data->max));
+
grn_gton(geo_key_top_left, top_left, sizeof(grn_geo_point));
grn_gton(geo_key_bottom_right, bottom_right, sizeof(grn_geo_point));
data->rectangle_common_bit =
compute_diff_bit(geo_key_top_left, geo_key_bottom_right) - 1;
- compute_min_and_max(&(data->base), data->diff_bit,
- &(data->min), &(data->max));
+ compute_min_and_max_key(geo_key_top_left, data->rectangle_common_bit + 1,
+ data->rectangle_common_key, NULL);
+
switch (data->direction) {
case GRN_GEO_MESH_LATITUDE :
data->distance = data->max.latitude - data->min.latitude + 1;
@@ -1052,15 +1074,16 @@ grn_geo_cursor_open_in_rectangle(grn_ctx *ctx,
cursor->current_entry = 0;
{
grn_geo_cursor_entry *entry;
+
entry = &(cursor->entries[cursor->current_entry]);
entry->target_bit = data.rectangle_common_bit;
+ memcpy(entry->base_key, data.rectangle_common_key, sizeof(grn_geo_point));
entry->top_included = GRN_TRUE;
entry->bottom_included = GRN_TRUE;
entry->left_included = GRN_TRUE;
entry->right_included = GRN_TRUE;
entry->latitude_inner = GRN_FALSE;
entry->longitude_inner = GRN_FALSE;
- grn_gton(entry->base_key, &(data.base), sizeof(grn_geo_point));
}
exit :
@@ -1315,9 +1338,7 @@ grn_geo_cursor_each_strictly(grn_ctx *ctx, grn_obj *geo_cursor,
return;
}
#ifdef GEO_DEBUG
- {
- inspect_mesh(ctx, &entry_base, entry.target_bit, 0);
- }
+ inspect_mesh(ctx, &entry_base, entry.target_bit, 0);
#endif
}