[Groonga-commit] groonga/groonga [master] [suggest] pass unknown parameters to groonga.

Back to archive index

null+****@clear***** null+****@clear*****
2012年 1月 25日 (水) 12:04:30 JST


Kouhei Sutou	2012-01-25 12:04:30 +0900 (Wed, 25 Jan 2012)

  New Revision: bca5b949328de759aae7769c764d50575b7557f9

  Log:
    [suggest] pass unknown parameters to groonga.

  Modified files:
    src/suggest/groonga_suggest_httpd.c
    src/suggest/groonga_suggest_learner.c
    src/suggest/util.c
    src/suggest/util.h

  Modified: src/suggest/groonga_suggest_httpd.c (+26 -8)
===================================================================
--- src/suggest/groonga_suggest_httpd.c    2012-01-25 10:48:19 +0900 (6346ae6)
+++ src/suggest/groonga_suggest_httpd.c    2012-01-25 12:04:30 +0900 (118637d)
@@ -68,6 +68,7 @@ typedef struct {
   grn_obj *db;
   void *zmq_sock;
   grn_obj cmd_buf;
+  grn_obj pass_through_parameters;
   pthread_t thd;
   uint32_t thread_id;
   struct event_base *base;
@@ -96,10 +97,11 @@ static grn_obj *db;
 static uint32_t n_lines_per_log_file = 1000000;
 
 static int
-suggest_result(struct evbuffer *res_buf, const char *types, const char *query,
+suggest_result(grn_ctx *ctx,
+               struct evbuffer *res_buf, const char *types, const char *query,
                const char *target_name, int frequency_threshold,
                double conditional_probability_threshold, int limit,
-               grn_obj *cmd_buf, grn_ctx *ctx)
+               grn_obj *cmd_buf, grn_obj *pass_through_parameters)
 {
   if (target_name && types && query) {
     GRN_BULK_REWIND(cmd_buf);
@@ -115,6 +117,12 @@ suggest_result(struct evbuffer *res_buf, const char *types, const char *query,
     grn_text_ftoa(ctx, cmd_buf, conditional_probability_threshold);
     GRN_TEXT_PUTS(ctx, cmd_buf, "&limit=");
     grn_text_itoa(ctx, cmd_buf, limit);
+    if (GRN_TEXT_LEN(pass_through_parameters) > 0) {
+      GRN_TEXT_PUTS(ctx, cmd_buf, "&");
+      GRN_TEXT_PUT(ctx, cmd_buf,
+                   GRN_TEXT_VALUE(pass_through_parameters),
+                   GRN_TEXT_LEN(pass_through_parameters));
+    }
     {
       char *res;
       int flags;
@@ -142,9 +150,11 @@ log_send(struct evkeyvalq *output_headers, struct evbuffer *res_buf,
   const char *callback, *types, *query, *client_id, *target_name,
              *learn_target_name;
 
-  parse_keyval(get_args, &query, &types, &client_id, &target_name,
+  GRN_BULK_REWIND(&(thd->pass_through_parameters));
+  parse_keyval(thd->ctx, get_args, &query, &types, &client_id, &target_name,
                &learn_target_name, &callback, &millisec, &frequency_threshold,
-               &conditional_probability_threshold, &limit);
+               &conditional_probability_threshold, &limit,
+               &(thd->pass_through_parameters));
 
   /* send data to learn client */
   if (thd->zmq_sock && millisec && client_id && query && learn_target_name) {
@@ -218,18 +228,24 @@ log_send(struct evkeyvalq *output_headers, struct evbuffer *res_buf,
       content_length = strlen(callback);
       evbuffer_add(res_buf, callback, content_length);
       evbuffer_add(res_buf, "(", 1);
-      content_length += suggest_result(res_buf, types, query, target_name,
+      content_length += suggest_result(thd->ctx,
+                                       res_buf, types, query, target_name,
                                        frequency_threshold,
                                        conditional_probability_threshold,
-                                       limit, &(thd->cmd_buf), thd->ctx) + 3;
+                                       limit,
+                                       &(thd->cmd_buf),
+                                       &(thd->pass_through_parameters)) + 3;
       evbuffer_add(res_buf, ");", 2);
     } else {
       evhttp_add_header(output_headers,
                         "Content-Type", "application/json; charset=UTF-8");
-      content_length = suggest_result(res_buf, types, query, target_name,
+      content_length = suggest_result(thd->ctx,
+                                      res_buf, types, query, target_name,
                                       frequency_threshold,
                                       conditional_probability_threshold,
-                                      limit, &(thd->cmd_buf), thd->ctx);
+                                      limit,
+                                      &(thd->cmd_buf),
+                                      &(thd->pass_through_parameters));
     }
     if (content_length >= 0) {
       char num_buf[16];
@@ -251,6 +267,7 @@ cleanup_httpd_thread(thd_data *thd) {
     zmq_close(thd->zmq_sock);
   }
   grn_obj_unlink(thd->ctx, &(thd->cmd_buf));
+  grn_obj_unlink(thd->ctx, &(thd->pass_through_parameters));
   if (thd->ctx) {
     grn_ctx_close(thd->ctx);
   }
@@ -591,6 +608,7 @@ serve_threads(int nthreads, int port, const char *db_path, void *zmq_ctx,
             print_error("error in grn_db_open() on thread %d.", i);
           } else {
             GRN_TEXT_INIT(&(threads[i].cmd_buf), 0);
+            GRN_TEXT_INIT(&(threads[i].pass_through_parameters), 0);
             threads[i].log_base_path = log_base_path;
             threads[i].thread_id = i;
             evhttp_set_gencb(threads[i].httpd, generic_handler, &threads[i]);

  Modified: src/suggest/groonga_suggest_learner.c (+4 -2)
===================================================================
--- src/suggest/groonga_suggest_learner.c    2012-01-25 10:48:19 +0900 (214b2f8)
+++ src/suggest/groonga_suggest_learner.c    2012-01-25 12:04:30 +0900 (bf6a655)
@@ -542,8 +542,10 @@ read_log_line(suggest_log_file **list)
         struct evkeyvalq get_args;
         *eol = '\0';
         evhttp_parse_query(line_buf, &get_args);
-        parse_keyval(&get_args, &query, &types, &client_id, NULL,
-                     &learn_target_name, NULL, &(t->millisec), NULL, NULL, NULL);
+        parse_keyval(NULL,
+                     &get_args, &query, &types, &client_id, NULL,
+                     &learn_target_name, NULL, &(t->millisec), NULL, NULL, NULL,
+                     NULL);
         if (query && client_id && learn_target_name && t->millisec) {
           t->query = evhttp_decode_uri(query);
           t->submit = (types && !strcmp(types, "submit"));

  Modified: src/suggest/util.c (+89 -52)
===================================================================
--- src/suggest/util.c    2012-01-25 10:48:19 +0900 (6852760)
+++ src/suggest/util.c    2012-01-25 12:04:30 +0900 (793d55c)
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 
 #include "util.h"
+#include <evhttp.h>
 
 #define DEFAULT_FREQUENCY_THRESHOLD 100
 #define DEFAULT_CONDITIONAL_PROBABILITY_THRESHOLD 0.2
@@ -95,7 +96,8 @@ atouint64_t(const char *s)
 }
 
 void
-parse_keyval(struct evkeyvalq *get_args,
+parse_keyval(grn_ctx *ctx,
+             struct evkeyvalq *get_args,
              const char **query, const char **types,
              const char **client_id, const char **target_name,
              const char **learn_target_name,
@@ -103,7 +105,8 @@ parse_keyval(struct evkeyvalq *get_args,
              uint64_t *millisec,
              int *frequency_threshold,
              double *conditional_probability_threshold,
-             int *limit)
+             int *limit,
+             grn_obj *pass_through_parameters)
 {
   struct evkeyval *get;
 
@@ -123,61 +126,95 @@ parse_keyval(struct evkeyvalq *get_args,
   if (limit) { *limit = -1; }
 
   TAILQ_FOREACH(get, get_args, next) {
-    switch(get->key[0]) {
-    case 'q':
-      if (query) {
-        *query = get->value;
-      }
-      break;
-    case 't':
-      /* TODO: check types */
-      if (types) {
-        *types = get->value;
-      }
-      break;
-    case 'i':
-      if (client_id) {
-        *client_id = get->value;
-      }
-      break;
-    case 'c':
-      if (!strcmp(get->key, "callback") && callback) {
-        *callback = get->value;
-      }
-      break;
-    case 's':
-      if (millisec) {
-        *millisec = atouint64_t(get->value);
-      }
-      break;
-    case 'n':
-      /* TODO: check target_name */
-      if (target_name) {
-        *target_name = get->value;
-      }
-      break;
-    case 'l':
-      if (learn_target_name) {
-        *learn_target_name = get->value;
-      }
+    grn_bool is_pass_through_parameter = GRN_FALSE;
+    size_t key_length;
+
+    key_length = strlen(get->key);
+    switch (key_length) {
+    case 0:
       break;
-    case 'h':
-      if (frequency_threshold) {
-        *frequency_threshold = atoi(get->value);
+    case 1:
+      switch(get->key[0]) {
+      case 'q':
+        if (query) {
+          *query = get->value;
+        }
+        break;
+      case 't':
+        /* TODO: check types */
+        if (types) {
+          *types = get->value;
+        }
+        break;
+      case 'i':
+        if (client_id) {
+          *client_id = get->value;
+        }
+        break;
+      case 's':
+        if (millisec) {
+          *millisec = atouint64_t(get->value);
+        }
+        break;
+      case 'n':
+        /* TODO: check target_name */
+        if (target_name) {
+          *target_name = get->value;
+        }
+        break;
+      case 'l':
+        if (learn_target_name) {
+          *learn_target_name = get->value;
+        }
+        break;
+      case 'h':
+        if (frequency_threshold) {
+          *frequency_threshold = atoi(get->value);
+        }
+        break;
+      case 'p':
+        if (conditional_probability_threshold) {
+          *conditional_probability_threshold = strtod(get->value, NULL);
+        }
+        break;
+      case 'm':
+        if (limit) {
+          *limit = atoi(get->value);
+        }
+        break;
+      default:
+        is_pass_through_parameter = GRN_TRUE;
+        break;
       }
       break;
-    case 'p':
-      if (conditional_probability_threshold) {
-        *conditional_probability_threshold = strtod(get->value, NULL);
+    default:
+      switch (get->key[0]) {
+      case 'c':
+        if (!strcmp(get->key, "callback")) {
+          if (callback) {
+            *callback = get->value;
+          }
+        } else {
+          is_pass_through_parameter = GRN_TRUE;
+        }
+        break;
+      default:
+        is_pass_through_parameter = GRN_TRUE;
       }
-      break;
-    case 'm':
-      if (limit) {
-        *limit = atoi(get->value);
+    }
+
+    if (is_pass_through_parameter && pass_through_parameters) {
+      char *encoded_key = NULL, *encoded_value = NULL;
+      encoded_key = evhttp_uriencode(get->key, -1, 1);
+      encoded_value = evhttp_uriencode(get->value, -1, 1);
+      if (GRN_TEXT_LEN(pass_through_parameters) > 0) {
+        GRN_TEXT_PUTS(ctx, pass_through_parameters, "&");
       }
-      break;
-    default:
-      break;
+      GRN_TEXT_PUTS(ctx, pass_through_parameters, encoded_key);
+      GRN_TEXT_PUTS(ctx, pass_through_parameters, "=");
+      GRN_TEXT_PUTS(ctx, pass_through_parameters, encoded_value);
+      free(encoded_key);
+      free(encoded_value);
     }
   }
 }

  Modified: src/suggest/util.h (+6 -2)
===================================================================
--- src/suggest/util.h    2012-01-25 10:48:19 +0900 (831c5b7)
+++ src/suggest/util.h    2012-01-25 12:04:30 +0900 (a35dbe0)
@@ -21,9 +21,12 @@
 #include <event.h>
 #include <stdint.h>
 
+#include <groonga.h>
+
 int print_error(const char *format, ...);
 int daemonize(void);
-void parse_keyval(struct evkeyvalq *get_args,
+void parse_keyval(grn_ctx *ctx,
+                  struct evkeyvalq *get_args,
                   const char **query, const char **types,
                   const char **client_id, const char **target_name,
                   const char **learn_target_name,
@@ -31,6 +34,7 @@ void parse_keyval(struct evkeyvalq *get_args,
                   uint64_t *millisec,
                   int *frequency_threshold,
                   double *conditional_probability_threshold,
-                  int *limit);
+                  int *limit,
+                  grn_obj *pass_through_parameters);
 
 #endif /* GRN_SUGGEST_UTIL_H */




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