null+****@clear*****
null+****@clear*****
2011年 9月 24日 (土) 18:49:07 JST
Kouhei Sutou 2011-09-24 09:49:07 +0000 (Sat, 24 Sep 2011)
New Revision: b01e0343d9b0cffe3309ecefe1cd1bd2ba16c4e3
Log:
[storage] support records_in_range for MBRContains.
TODO: implement index_* for MBRContains.
Modified files:
ha_mroonga.cc
ha_mroonga.h
Modified: ha_mroonga.cc (+85 -7)
===================================================================
--- ha_mroonga.cc 2011-09-24 09:43:36 +0000 (043f671)
+++ ha_mroonga.cc 2011-09-24 09:49:07 +0000 (7ba90ec)
@@ -3894,13 +3894,18 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
DBUG_RETURN((ha_rows)1) ;
}
- if (range_min) {
- mrn_set_key_buf(ctx, field, range_min->key, key_min[key_nr], &size_min);
- val_min = key_min[key_nr];
- }
- if (range_max) {
- mrn_set_key_buf(ctx, field, range_max->key, key_max[key_nr], &size_max);
- val_max = key_max[key_nr];
+ if (field->type() == MYSQL_TYPE_GEOMETRY) {
+ row_count = storage_records_in_range_geo(key_nr, range_min, range_max);
+ DBUG_RETURN(row_count);
+ } else {
+ if (range_min) {
+ mrn_set_key_buf(ctx, field, range_min->key, key_min[key_nr], &size_min);
+ val_min = key_min[key_nr];
+ }
+ if (range_max) {
+ mrn_set_key_buf(ctx, field, range_max->key, key_max[key_nr], &size_max);
+ val_max = key_max[key_nr];
+ }
}
}
@@ -3951,6 +3956,79 @@ ha_rows ha_mroonga::storage_records_in_range(uint key_nr, key_range *range_min,
DBUG_RETURN(row_count);
}
+ha_rows ha_mroonga::storage_records_in_range_geo(uint key_nr,
+ key_range *range_min,
+ key_range *range_max)
+{
+ MRN_DBUG_ENTER_METHOD();
+ ha_rows row_count;
+
+ if (!range_min) {
+ DBUG_PRINT("info", ("range min is missing for geometry search"));
+ DBUG_RETURN(HA_POS_ERROR);
+ }
+ if (range_max) {
+ DBUG_PRINT("info", ("range max is specified for geometry search"));
+ DBUG_RETURN(HA_POS_ERROR);
+ }
+ if (!(range_min->flag & HA_READ_MBR_CONTAIN)) {
+ char search_name[MRN_BUFFER_SIZE];
+ if (range_min->flag & HA_READ_MBR_INTERSECT) {
+ strcpy(search_name, "intersect");
+ } else if (range_min->flag & HA_READ_MBR_WITHIN) {
+ strcpy(search_name, "within");
+ } else if (range_min->flag & HA_READ_MBR_DISJOINT) {
+ strcpy(search_name, "disjoint");
+ } else if (range_min->flag & HA_READ_MBR_EQUAL) {
+ strcpy(search_name, "equal");
+ } else {
+ sprintf(search_name, "unknown: %d", range_min->flag);
+ }
+ DBUG_PRINT("info",
+ ("spatial index search "
+ "except MBRContains aren't supported: <%s>"));
+ row_count = grn_table_size(ctx, grn_table);
+ DBUG_RETURN(row_count);
+ }
+
+ double locations[4];
+ for (int i = 0; i < 4; i++) {
+ uchar reversed_value[8];
+ for (int j = 0; j < 8; j++) {
+ reversed_value[j] = (range_min->key + (8 * i))[7 - j];
+ }
+ mi_float8get(locations[i], reversed_value);
+ }
+ double top_left_longitude = locations[0];
+ double bottom_right_longitude = locations[1];
+ double bottom_right_latitude = locations[2];
+ double top_left_latitude = locations[3];
+ grn_obj top_left_point, bottom_right_point;
+ GRN_WGS84_GEO_POINT_INIT(&top_left_point, 0);
+ GRN_WGS84_GEO_POINT_INIT(&bottom_right_point, 0);
+ GRN_GEO_POINT_SET(ctx, &top_left_point,
+ GRN_GEO_DEGREE2MSEC(top_left_latitude),
+ GRN_GEO_DEGREE2MSEC(top_left_longitude));
+ GRN_GEO_POINT_SET(ctx, &bottom_right_point,
+ GRN_GEO_DEGREE2MSEC(bottom_right_latitude),
+ GRN_GEO_DEGREE2MSEC(bottom_right_longitude));
+ grn_obj *result;
+ result = grn_table_create(ctx, NULL, 0, NULL,
+ GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
+ grn_table, NULL);
+ // TODO: check result isn't NULL.
+ grn_rc rc;
+ rc = grn_geo_select_in_rectangle(ctx, grn_index_columns[key_nr],
+ &top_left_point, &bottom_right_point,
+ result, GRN_OP_OR);
+ // TODO: check rc;
+ grn_obj_unlink(ctx, &top_left_point);
+ grn_obj_unlink(ctx, &bottom_right_point);
+ row_count = grn_table_size(ctx, result);
+ grn_obj_unlink(ctx, result);
+ DBUG_RETURN(row_count);
+}
+
ha_rows ha_mroonga::records_in_range(uint key_nr, key_range *range_min, key_range *range_max)
{
MRN_DBUG_ENTER_METHOD();
Modified: ha_mroonga.h (+2 -0)
===================================================================
--- ha_mroonga.h 2011-09-24 09:43:36 +0000 (0d7420a)
+++ ha_mroonga.h 2011-09-24 09:49:07 +0000 (5b6948f)
@@ -418,6 +418,8 @@ private:
key_range *range_max);
ha_rows storage_records_in_range(uint key_nr, key_range *range_min,
key_range *range_max);
+ ha_rows storage_records_in_range_geo(uint key_nr, key_range *range_min,
+ key_range *range_max);
int wrapper_index_init(uint idx, bool sorted);
int storage_index_init(uint idx, bool sorted);
int wrapper_index_end();