[Groonga-mysql-commit] mroonga/mroonga [master] [geo] cache geo search result.

アーカイブの一覧に戻る

null+****@clear***** null+****@clear*****
2011年 10月 12日 (水) 09:15:44 JST


Kouhei Sutou	2011-10-12 00:15:44 +0000 (Wed, 12 Oct 2011)

  New Revision: 24d3eea07cea236b860dd1931e6974b1d3d69610

  Log:
    [geo] cache geo search result.

  Modified files:
    ha_mroonga.cc
    ha_mroonga.h

  Modified: ha_mroonga.cc (+59 -27)
===================================================================
--- ha_mroonga.cc    2011-10-06 08:55:53 +0000 (802d7cd)
+++ ha_mroonga.cc    2011-10-12 00:15:44 +0000 (68dbeef)
@@ -1265,6 +1265,8 @@ ha_mroonga::ha_mroonga(handlerton *hton, TABLE_SHARE *share)
   cursor = NULL;
   index_table_cursor = NULL;
   result_geo = NULL;
+  GRN_WGS84_GEO_POINT_INIT(&top_left_point, 0);
+  GRN_WGS84_GEO_POINT_INIT(&bottom_right_point, 0);
   score_column = NULL;
   key_accessor = NULL;
   share = NULL;
@@ -1281,6 +1283,8 @@ ha_mroonga::ha_mroonga(handlerton *hton, TABLE_SHARE *share)
 ha_mroonga::~ha_mroonga()
 {
   MRN_DBUG_ENTER_METHOD();
+  grn_obj_unlink(ctx, &top_left_point);
+  grn_obj_unlink(ctx, &bottom_right_point);
   grn_obj_unlink(ctx, &key_buffer);
   grn_obj_unlink(ctx, &old_value_buffer);
   grn_obj_unlink(ctx, &new_value_buffer);
@@ -4196,10 +4200,11 @@ ha_rows ha_mroonga::generic_records_in_range_geo(uint key_nr,
     DBUG_RETURN(row_count);
   }
 
-  grn_obj *result = generic_geo_select_in_rectangle(grn_index_columns[key_nr],
-                                                    range_min->key);
-  row_count = grn_table_size(ctx, result);
-  grn_obj_unlink(ctx, result);
+  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);
   DBUG_RETURN(row_count);
 }
 
@@ -4295,7 +4300,7 @@ int ha_mroonga::wrapper_index_read_map(uchar * buf, const uchar * key,
   MRN_DBUG_ENTER_METHOD();
   KEY key_info = table->key_info[active_index];
   if (mrn_is_geo_key(&key_info)) {
-    clear_search_result();
+    clear_cursor();
     error = generic_geo_open_cursor(key, find_flag);
     if (!error) {
       error = wrapper_get_next_record(buf);
@@ -5389,6 +5394,12 @@ void ha_mroonga::clear_search_result()
     grn_obj_unlink(ctx, matched_record_keys);
     matched_record_keys = NULL;
   }
+  DBUG_VOID_RETURN;
+}
+
+void ha_mroonga::clear_search_result_geo()
+{
+  MRN_DBUG_ENTER_METHOD();
   if (result_geo) {
     grn_obj_unlink(ctx, result_geo);
     result_geo = NULL;
@@ -5498,9 +5509,13 @@ int ha_mroonga::storage_get_next_record(uchar *buf)
   DBUG_RETURN(0);
 }
 
-grn_obj *ha_mroonga::generic_geo_select_in_rectangle(grn_obj *index_column,
-                                                     const uchar *rectangle)
+int ha_mroonga::generic_geo_select_in_rectangle(grn_obj *index_column,
+                                                const uchar *rectangle)
 {
+  MRN_DBUG_ENTER_METHOD();
+
+  int error = 0;
+
   double locations[4];
   for (int i = 0; i < 4; i++) {
     uchar reversed_value[8];
@@ -5509,33 +5524,49 @@ grn_obj *ha_mroonga::generic_geo_select_in_rectangle(grn_obj *index_column,
     }
     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);
+  double top_left_longitude_in_degree = locations[0];
+  double bottom_right_longitude_in_degree = locations[1];
+  double bottom_right_latitude_in_degree = locations[2];
+  double top_left_latitude_in_degree = locations[3];
+  int top_left_latitude = GRN_GEO_DEGREE2MSEC(top_left_latitude_in_degree);
+  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,
-                    GRN_GEO_DEGREE2MSEC(top_left_latitude),
-                    GRN_GEO_DEGREE2MSEC(top_left_longitude));
+                    top_left_latitude, 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,
+                    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, GRN_OP_OR);
+                                   result_geo, GRN_OP_OR);
   // TODO: check rc;
-  grn_obj_unlink(ctx, &top_left_point);
-  grn_obj_unlink(ctx, &bottom_right_point);
 
-  return result;
+  DBUG_RETURN(error);
 }
 
 int ha_mroonga::generic_geo_open_cursor(const uchar *key,
@@ -5545,9 +5576,9 @@ int ha_mroonga::generic_geo_open_cursor(const uchar *key,
   int error = 0;
   int flags = 0;
   if (find_flag & HA_READ_MBR_CONTAIN) {
-    result_geo = generic_geo_select_in_rectangle(grn_index_columns[active_index],
-                                                 key);
-    // TODO: check result
+    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);
   } else {
@@ -5854,6 +5885,7 @@ int ha_mroonga::reset()
   MRN_DBUG_ENTER_METHOD();
   DBUG_PRINT("info", ("mroonga this=%p", this));
   clear_search_result();
+  clear_search_result_geo();
   if (share->wrapper_mode)
     error = wrapper_reset();
   else

  Modified: ha_mroonga.h (+5 -2)
===================================================================
--- ha_mroonga.h    2011-10-06 08:55:53 +0000 (3a9f9a4)
+++ ha_mroonga.h    2011-10-12 00:15:44 +0000 (84b7548)
@@ -132,6 +132,8 @@ private:
   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 *score_column;
@@ -331,11 +333,12 @@ private:
   void push_warning_unsupported_spatial_index_search(enum ha_rkey_function flag);
   void clear_cursor();
   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);
-  grn_obj *generic_geo_select_in_rectangle(grn_obj *index_column,
-                                           const uchar *rectangle);
+  int generic_geo_select_in_rectangle(grn_obj *index_column,
+                                      const uchar *rectangle);
   int generic_geo_open_cursor(const uchar *key, enum ha_rkey_function find_flag);
 
 #ifdef MRN_HANDLER_HAVE_HA_CLOSE




Groonga-mysql-commit メーリングリストの案内
アーカイブの一覧に戻る