null+****@clear*****
null+****@clear*****
2011年 10月 20日 (木) 18:18:41 JST
Kouhei Sutou 2011-10-20 09:18:41 +0000 (Thu, 20 Oct 2011)
New Revision: 643d4f647f5598dccc44974ebf34229e173dd7a3
Log:
[geo] use grn_geo_estimate_in_rectangle() and grn_geo_cursor_open_in_rectangle().
Modified files:
ha_mroonga.cc
ha_mroonga.h
test/sql/groonga_storage/r/geometry_contains.result
test/sql/groonga_wrapper/r/geometry_contains.result
Modified: ha_mroonga.cc (+78 -80)
===================================================================
--- ha_mroonga.cc 2011-10-19 05:48:26 +0000 (4f3477c)
+++ ha_mroonga.cc 2011-10-20 09:18:41 +0000 (84e2d72)
@@ -1291,7 +1291,7 @@ ha_mroonga::ha_mroonga(handlerton *hton, TABLE_SHARE *share)
grn_columns = NULL;
cursor = NULL;
index_table_cursor = NULL;
- result_geo = NULL;
+ geo_cursor = NULL;
GRN_WGS84_GEO_POINT_INIT(&top_left_point, 0);
GRN_WGS84_GEO_POINT_INIT(&bottom_right_point, 0);
score_column = NULL;
@@ -4261,11 +4261,11 @@ ha_rows ha_mroonga::generic_records_in_range_geo(uint key_nr,
DBUG_RETURN(row_count);
}
- int error;
- error = generic_geo_select_in_rectangle(grn_index_columns[key_nr],
- range_min->key);
- // TODO: check error.
- row_count = grn_table_size(ctx, result_geo);
+ geo_store_rectangle(range_min->key);
+ row_count = grn_geo_estimate_in_rectangle(ctx,
+ grn_index_columns[key_nr],
+ &top_left_point,
+ &bottom_right_point);
DBUG_RETURN(row_count);
}
@@ -4362,6 +4362,7 @@ int ha_mroonga::wrapper_index_read_map(uchar * buf, const uchar * key,
KEY key_info = table->key_info[active_index];
if (mrn_is_geo_key(&key_info)) {
clear_cursor();
+ clear_cursor_geo();
error = generic_geo_open_cursor(key, find_flag);
if (!error) {
error = wrapper_get_next_record(buf);
@@ -4395,6 +4396,7 @@ int ha_mroonga::storage_index_read_map(uchar *buf, const uchar *key,
const void *val_min = NULL, *val_max = NULL;
clear_search_result();
+ clear_search_result_geo();
bool is_multiple_column_index = key_info.key_parts > 1;
if (is_multiple_column_index) {
@@ -5437,7 +5439,7 @@ void ha_mroonga::clear_cursor()
key_accessor = NULL;
}
if (cursor) {
- grn_table_cursor_close(ctx, cursor);
+ grn_obj_unlink(ctx, cursor);
cursor = NULL;
}
if (index_table_cursor) {
@@ -5447,6 +5449,16 @@ void ha_mroonga::clear_cursor()
DBUG_VOID_RETURN;
}
+void ha_mroonga::clear_cursor_geo()
+{
+ MRN_DBUG_ENTER_METHOD();
+ if (geo_cursor) {
+ grn_obj_unlink(ctx, geo_cursor);
+ geo_cursor = NULL;
+ }
+ DBUG_VOID_RETURN;
+}
+
void ha_mroonga::clear_search_result()
{
MRN_DBUG_ENTER_METHOD();
@@ -5461,10 +5473,7 @@ void ha_mroonga::clear_search_result()
void ha_mroonga::clear_search_result_geo()
{
MRN_DBUG_ENTER_METHOD();
- if (result_geo) {
- grn_obj_unlink(ctx, result_geo);
- result_geo = NULL;
- }
+ clear_cursor_geo();
DBUG_VOID_RETURN;
}
@@ -5502,13 +5511,28 @@ int ha_mroonga::wrapper_get_next_record(uchar *buf)
MRN_DBUG_ENTER_METHOD();
int error = 0;
do {
- grn_id found_record_id = grn_table_cursor_next(ctx, cursor);
- if (found_record_id == GRN_ID_NIL) {
- error = HA_ERR_END_OF_FILE;
- clear_cursor();
- break;
+ GRN_BULK_REWIND(&key_buffer);
+ if (geo_cursor) {
+ grn_id found_record_id;
+ grn_posting *posting;
+ posting = grn_geo_cursor_next(ctx, geo_cursor);
+ if (!posting) {
+ error = HA_ERR_END_OF_FILE;
+ clear_cursor_geo();
+ break;
+ }
+ found_record_id = posting->rid;
+ grn_table_get_key(ctx, grn_table, found_record_id,
+ GRN_TEXT_VALUE(&key_buffer),
+ table->key_info->key_length);
} else {
- GRN_BULK_REWIND(&key_buffer);
+ grn_id found_record_id;
+ found_record_id = grn_table_cursor_next(ctx, cursor);
+ if (found_record_id == GRN_ID_NIL) {
+ error = HA_ERR_END_OF_FILE;
+ clear_cursor();
+ break;
+ }
if (key_accessor) {
grn_obj_get_value(ctx, key_accessor, found_record_id, &key_buffer);
} else {
@@ -5517,24 +5541,25 @@ int ha_mroonga::wrapper_get_next_record(uchar *buf)
key_length = grn_table_cursor_get_key(ctx, cursor, &key);
GRN_TEXT_SET(ctx, &key_buffer, key, key_length);
}
- MRN_SET_WRAP_SHARE_KEY(share, table->s);
- MRN_SET_WRAP_TABLE_KEY(this, table);
+ }
+
+ MRN_SET_WRAP_SHARE_KEY(share, table->s);
+ MRN_SET_WRAP_TABLE_KEY(this, table);
#ifdef MRN_HANDLER_HAVE_HA_INDEX_READ_IDX_MAP
- error = wrap_handler->ha_index_read_idx_map(buf,
- share->wrap_primary_key,
- (uchar *)GRN_TEXT_VALUE(&key_buffer),
- pk_keypart_map,
- HA_READ_KEY_EXACT);
+ error = wrap_handler->ha_index_read_idx_map(buf,
+ share->wrap_primary_key,
+ (uchar *)GRN_TEXT_VALUE(&key_buffer),
+ pk_keypart_map,
+ HA_READ_KEY_EXACT);
#else
- error = wrap_handler->index_read_idx_map(buf,
- share->wrap_primary_key,
- (uchar *)GRN_TEXT_VALUE(&key_buffer),
- pk_keypart_map,
- HA_READ_KEY_EXACT);
+ error = wrap_handler->index_read_idx_map(buf,
+ share->wrap_primary_key,
+ (uchar *)GRN_TEXT_VALUE(&key_buffer),
+ pk_keypart_map,
+ HA_READ_KEY_EXACT);
#endif
- MRN_SET_BASE_SHARE_KEY(share, table->s);
- MRN_SET_BASE_TABLE_KEY(this, table);
- }
+ MRN_SET_BASE_SHARE_KEY(share, table->s);
+ MRN_SET_BASE_TABLE_KEY(this, table);
} while (error == HA_ERR_END_OF_FILE);
DBUG_RETURN(error);
}
@@ -5542,23 +5567,24 @@ int ha_mroonga::wrapper_get_next_record(uchar *buf)
int ha_mroonga::storage_get_next_record(uchar *buf)
{
MRN_DBUG_ENTER_METHOD();
- record_id = grn_table_cursor_next(ctx, cursor);
+ if (geo_cursor) {
+ grn_posting *posting;
+ posting = grn_geo_cursor_next(ctx, geo_cursor);
+ if (posting) {
+ record_id = posting->rid;
+ } else {
+ record_id = GRN_ID_NIL;
+ }
+ } else {
+ record_id = grn_table_cursor_next(ctx, cursor);
+ }
if (ctx->rc) {
int error = ER_ERROR_ON_READ;
my_message(error, ctx->errbuf, MYF(0));
clear_search_result();
+ clear_search_result_geo();
DBUG_RETURN(error);
}
- if (result_geo && record_id) {
- grn_id real_record_id;
- if (grn_table_get_key(ctx, result_geo, record_id,
- &real_record_id, sizeof(real_record_id))) {
- record_id = real_record_id;
- } else {
- // TODO: handle not found case.
- record_id = GRN_ID_NIL;
- }
- }
if (record_id == GRN_ID_NIL) {
table->status = STATUS_NOT_FOUND;
DBUG_RETURN(HA_ERR_END_OF_FILE);
@@ -5570,8 +5596,7 @@ int ha_mroonga::storage_get_next_record(uchar *buf)
DBUG_RETURN(0);
}
-int ha_mroonga::generic_geo_select_in_rectangle(grn_obj *index_column,
- const uchar *rectangle)
+void ha_mroonga::geo_store_rectangle(const uchar *rectangle)
{
MRN_DBUG_ENTER_METHOD();
@@ -5593,41 +5618,12 @@ int ha_mroonga::generic_geo_select_in_rectangle(grn_obj *index_column,
int top_left_longitude = GRN_GEO_DEGREE2MSEC(top_left_longitude_in_degree);
int bottom_right_latitude = GRN_GEO_DEGREE2MSEC(bottom_right_latitude_in_degree);
int bottom_right_longitude = GRN_GEO_DEGREE2MSEC(bottom_right_longitude_in_degree);
- if (result_geo) {
- int cached_top_left_latitude, cached_top_left_longitude;
- int cached_bottom_right_latitude, cached_bottom_right_longitude;
- GRN_GEO_POINT_VALUE(&top_left_point,
- cached_top_left_latitude,
- cached_top_left_longitude);
- GRN_GEO_POINT_VALUE(&bottom_right_point,
- cached_bottom_right_latitude,
- cached_bottom_right_longitude);
- if (top_left_latitude == cached_top_left_latitude &&
- top_left_longitude == cached_top_left_longitude &&
- bottom_right_latitude == cached_bottom_right_latitude &&
- bottom_right_longitude == cached_bottom_right_longitude) {
- DBUG_PRINT("info", ("mroonga: reuse geo search result."));
- DBUG_RETURN(error);
- } else {
- clear_search_result_geo();
- }
- }
GRN_GEO_POINT_SET(ctx, &top_left_point,
top_left_latitude, top_left_longitude);
GRN_GEO_POINT_SET(ctx, &bottom_right_point,
bottom_right_latitude, bottom_right_longitude);
- result_geo = 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, index_column,
- &top_left_point, &bottom_right_point,
- result_geo, GRN_OP_OR);
- // TODO: check rc;
-
- DBUG_RETURN(error);
+ DBUG_VOID_RETURN;
}
int ha_mroonga::generic_geo_open_cursor(const uchar *key,
@@ -5637,11 +5633,13 @@ int ha_mroonga::generic_geo_open_cursor(const uchar *key,
int error = 0;
int flags = 0;
if (find_flag & HA_READ_MBR_CONTAIN) {
- error = generic_geo_select_in_rectangle(grn_index_columns[active_index],
- key);
- // TODO: check error
- cursor = grn_table_cursor_open(ctx, result_geo, NULL, 0, NULL, 0,
- 0, -1, flags);
+ grn_obj *index = grn_index_columns[active_index];
+ geo_store_rectangle(key);
+ geo_cursor = grn_geo_cursor_open_in_rectangle(ctx,
+ index,
+ &top_left_point,
+ &bottom_right_point,
+ 0, -1);
} else {
push_warning_unsupported_spatial_index_search(find_flag);
cursor = grn_table_cursor_open(ctx, grn_table, NULL, 0, NULL, 0,
Modified: ha_mroonga.h (+3 -3)
===================================================================
--- ha_mroonga.h 2011-10-19 05:48:26 +0000 (84b7548)
+++ ha_mroonga.h 2011-10-20 09:18:41 +0000 (dc82e43)
@@ -131,11 +131,11 @@ private:
grn_obj **grn_index_tables;
grn_obj **grn_index_columns;
- grn_obj *result_geo;
grn_obj top_left_point;
grn_obj bottom_right_point;
grn_table_cursor *cursor;
grn_table_cursor *index_table_cursor;
+ grn_obj *geo_cursor;
grn_obj *score_column;
grn_obj *key_accessor;
@@ -332,13 +332,13 @@ protected:
private:
void push_warning_unsupported_spatial_index_search(enum ha_rkey_function flag);
void clear_cursor();
+ void clear_cursor_geo();
void clear_search_result();
void clear_search_result_geo();
grn_obj *find_tokenizer(const char *name, int name_length);
int wrapper_get_next_record(uchar *buf);
int storage_get_next_record(uchar *buf);
- int generic_geo_select_in_rectangle(grn_obj *index_column,
- const uchar *rectangle);
+ void geo_store_rectangle(const uchar *rectangle);
int generic_geo_open_cursor(const uchar *key, enum ha_rkey_function find_flag);
#ifdef MRN_HANDLER_HAVE_HA_CLOSE
Modified: test/sql/groonga_storage/r/geometry_contains.result (+1 -1)
===================================================================
--- test/sql/groonga_storage/r/geometry_contains.result 2011-10-19 05:48:26 +0000 (9932614)
+++ test/sql/groonga_storage/r/geometry_contains.result 2011-10-20 09:18:41 +0000 (ce1a3c6)
@@ -163,7 +163,7 @@ id name location_text
select id, name, AsText(location) as location_text from shops
where MBRContains(GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location);
id name location_text
-26 kazuya POINT(139.760895 35.67350777777778)
14 tetsuji POINT(139.76857 35.680911944444446)
19 daruma POINT(139.7705988888889 35.68146083333333)
+26 kazuya POINT(139.760895 35.67350777777778)
drop table shops;
Modified: test/sql/groonga_wrapper/r/geometry_contains.result (+1 -1)
===================================================================
--- test/sql/groonga_wrapper/r/geometry_contains.result 2011-10-19 05:48:26 +0000 (dfc4ac4)
+++ test/sql/groonga_wrapper/r/geometry_contains.result 2011-10-20 09:18:41 +0000 (2ae5f67)
@@ -163,7 +163,7 @@ id name location_text
select id, name, AsText(location) as location_text from shops
where MBRContains(GeomFromText('LineString(139.7727 35.6684, 139.7038 35.7121)'), location);
id name location_text
-26 kazuya POINT(139.760895 35.673508)
14 tetsuji POINT(139.76857 35.680912)
19 daruma POINT(139.770599 35.681461)
+26 kazuya POINT(139.760895 35.673508)
drop table shops;