[Groonga-mysql-commit] mroonga/mroonga [master] [geo] use grn_geo_estimate_in_rectangle() and grn_geo_cursor_open_in_rectangle().

Back to archive index

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;




Groonga-mysql-commit メーリングリストの案内
Back to archive index