summaryrefslogtreecommitdiffstats
path: root/storage/mroonga/vendor/groonga/benchmark
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/Makefile.am153
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c276
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-cache.c155
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c198
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c506
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c276
-rwxr-xr-xstorage/mroonga/vendor/groonga/benchmark/bench-geo-select.sh38
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c275
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer-ddl.grn16
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c214
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-range-select.c280
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-result-set.c151
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c277
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/fixtures/Makefile.am2
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/13_2010.CSV.xzbin0 -> 2355640 bytes
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/Makefile.am4
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/README.txt6
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/format_2010.html111
-rwxr-xr-xstorage/mroonga/vendor/groonga/benchmark/geo-distance-summary.rb140
-rwxr-xr-xstorage/mroonga/vendor/groonga/benchmark/geo-select-generate-grn.rb53
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am24
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.c315
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.h64
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.c83
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.h34
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/lib/benchmark.c35
-rw-r--r--storage/mroonga/vendor/groonga/benchmark/lib/benchmark.h32
27 files changed, 3718 insertions, 0 deletions
diff --git a/storage/mroonga/vendor/groonga/benchmark/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/Makefile.am
new file mode 100644
index 00000000..a2a8b29a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/Makefile.am
@@ -0,0 +1,153 @@
+SUBDIRS = \
+ fixtures \
+ lib
+
+NONEXISTENT_CXX_SOURCE = nonexistent.cpp
+
+if WITH_BENCHMARK
+noinst_PROGRAMS = \
+ bench-table-factory \
+ bench-geo-distance \
+ bench-geo-select \
+ bench-ctx-create \
+ bench-query-optimizer \
+ bench-range-select \
+ bench-result-set \
+ bench-between-sequential \
+ bench-nfkc \
+ bench-cache
+endif
+
+EXTRA_DIST = \
+ bench-geo-select.sh \
+ bench-query-optimizer-ddl.grn \
+ geo-select-generate-grn.rb
+
+AM_CPPFLAGS = \
+ -I$(srcdir) \
+ -I$(srcdir)/lib \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/lib \
+ $(GROONGA_INCLUDEDIR)
+
+AM_CFLAGS = \
+ $(GLIB_CFLAGS)
+
+LIBS = \
+ $(top_builddir)/lib/libgroonga.la \
+ $(top_builddir)/benchmark/lib/libbenchmark.la \
+ $(GLIB_LIBS)
+
+bench_table_factory_SOURCES = bench-table-factory.c
+nodist_EXTRA_bench_table_factory_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_geo_distance_SOURCES = bench-geo-distance.c
+nodist_EXTRA_bench_geo_distance_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_geo_select_SOURCES = bench-geo-select.c
+nodist_EXTRA_bench_geo_select_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_ctx_create_SOURCES = bench-ctx-create.c
+nodist_EXTRA_bench_ctx_create_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_query_optimizer_SOURCES = bench-query-optimizer.c
+nodist_EXTRA_bench_query_optimizer_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_range_select_SOURCES = bench-range-select.c
+nodist_EXTRA_bench_range_select_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_result_set_SOURCES = bench-result-set.c
+nodist_EXTRA_bench_result_set_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_between_sequential_SOURCES = bench-between-sequential.c
+nodist_EXTRA_bench_between_sequential_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_nfkc_SOURCES = bench-nfkc.c
+nodist_EXTRA_bench_nfkc_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+bench_cache_SOURCES = bench-cache.c
+nodist_EXTRA_bench_cache_SOURCES = $(NONEXISTENT_CXX_SOURCE)
+
+benchmarks = \
+ run-bench-table-factory \
+ run-bench-geo-distance \
+ run-bench-geo-select \
+ run-bench-ctx-create \
+ run-bench-query-optimizer \
+ run-bench-range-select \
+ run-bench-result-set \
+ run-bench-between-sequential \
+ run-bench-nfkc \
+ run-bench-cache
+
+run-bench-table-factory: bench-table-factory
+ @echo $@:
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-table-factory
+
+run-bench-geo-distance: bench-geo-distance
+ @echo $@:
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-geo-distance
+
+run-bench-geo-select: bench-geo-select
+ @echo $@:
+ env \
+ RUBY="$(RUBY)" \
+ GROONGA="$(GROONGA)" \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ srcdir="$(srcdir)" \
+ $(srcdir)/bench-geo-select.sh
+
+run-bench-ctx-create: bench-ctx-create
+ @echo $@:
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-ctx-create
+
+run-bench-query-optimizer: bench-query-optimizer
+ @echo $@:
+ @rm -rf tmp/query-optimizer
+ @mkdir -p tmp/query-optimizer
+ @env \
+ GRN_RUBY_SCRIPTS_DIR=$(top_srcdir)/lib/mrb/scripts \
+ ../src/groonga \
+ --file $(srcdir)/bench-query-optimizer-ddl.grn \
+ -n tmp/query-optimizer/db > /dev/null
+ env \
+ GRN_RUBY_SCRIPTS_DIR=$(top_srcdir)/lib/mrb/scripts \
+ ./bench-query-optimizer
+
+run-bench-range-select: bench-range-select
+ @echo $@:
+ @[ ! -e tmp ] && ln -s /dev/shm tmp || :
+ @mkdir -p tmp/range-select
+ env \
+ GRN_RUBY_SCRIPTS_DIR=$(top_srcdir)/lib/mrb/scripts \
+ ./bench-range-select
+
+run-bench-result-set: bench-result-set
+ @echo $@:
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-result-set
+
+run-bench-between-sequential: bench-between-sequential
+ @echo $@:
+ @[ ! -e tmp ] && ln -s /dev/shm tmp || :
+ @mkdir -p tmp/between-sequential
+ env \
+ GRN_RUBY_SCRIPTS_DIR="$(top_srcdir)/lib/mrb/scripts" \
+ ./bench-between-sequential
+
+run-bench-nfkc: bench-nfkc
+ @echo $@:
+ ./bench-nfkc
+
+run-bench-cache: bench-cache
+ @echo $@:
+ ./bench-cache
+
+benchmark: $(benchmarks)
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c b/storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c
new file mode 100644
index 00000000..f0b7cf05
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-between-sequential.c
@@ -0,0 +1,276 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+/*
+ Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
+
+ CFLAGS: -O2 -g
+
+ Groonga: e2971d9a555a90724b76964cc8c8805373500b4a
+ % make --quiet -C benchmark run-bench-between-sequential
+ run-bench-between-sequential:
+ Process 10 times in each pattern
+ (total) (average) (median)
+ ( 500, 600] ( 1000): between: (0.0528s) (0.0053s) (0.0043s)
+ ( 500, 600] ( 1000): range: (0.0120s) (0.0012s) (0.2500ms)
+ ( 5000, 5100] ( 10000): between: (0.4052s) (0.0405s) (0.0395s)
+ ( 5000, 5100] ( 10000): range: (0.0197s) (0.0020s) (0.0010s)
+ ( 50000, 50100] ( 100000): between: (3.9343s) (0.3934s) (0.3900s)
+ ( 50000, 50100] ( 100000): range: (0.0969s) (0.0097s) (0.0088s)
+ (500000, 500100] (1000000): between: (38.2969s) (3.8297s) (3.7983s)
+ (500000, 500100] (1000000): range: (0.9158s) (0.0916s) (0.0900s)
+
+ Groonga: 35e4e431bb7660b3170e98c329f7219bd6723f05
+ % make --quiet -C benchmark run-bench-between-sequential
+ run-bench-between-sequential:
+ Process 10 times in each pattern
+ (total) (average) (median)
+ ( 500, 600] ( 1000): between: (0.0130s) (0.0013s) (0.2590ms)
+ ( 500, 600] ( 1000): range: (0.0124s) (0.0012s) (0.2530ms)
+ ( 5000, 5100] ( 10000): between: (0.0163s) (0.0016s) (0.6440ms)
+ ( 5000, 5100] ( 10000): range: (0.0205s) (0.0021s) (0.0011s)
+ ( 50000, 50100] ( 100000): between: (0.0611s) (0.0061s) (0.0051s)
+ ( 50000, 50100] ( 100000): range: (0.1004s) (0.0100s) (0.0091s)
+ (500000, 500100] (1000000): between: (0.4518s) (0.0452s) (0.0442s)
+ (500000, 500100] (1000000): range: (0.8866s) (0.0887s) (0.0878s)
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grn_db.h>
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+#define GET(context, name) (grn_ctx_get(context, name, strlen(name)))
+
+typedef struct _BenchmarkData
+{
+ grn_ctx context;
+ grn_obj *database;
+ guint n_records;
+ const gchar *command;
+} BenchmarkData;
+
+static void
+run_command(grn_ctx *context, const gchar *command)
+{
+ gchar *response;
+ unsigned int response_length;
+ int flags;
+
+ grn_ctx_send(context, command, strlen(command), 0);
+ grn_ctx_recv(context, &response, &response_length, &flags);
+}
+
+static void
+bench(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ grn_ctx *context = &(data->context);
+
+ run_command(context, data->command);
+}
+
+static gchar *
+get_tmp_dir(void)
+{
+ gchar *current_dir;
+ gchar *tmp_dir;
+
+ current_dir = g_get_current_dir();
+ tmp_dir = g_build_filename(current_dir, "tmp", NULL);
+ g_free(current_dir);
+
+ return tmp_dir;
+}
+
+static void
+setup_database(BenchmarkData *data)
+{
+ grn_ctx *context = &(data->context);
+ gchar *tmp_dir;
+ gchar *database_last_component_name;
+ gchar *database_path;
+ guint i;
+
+ tmp_dir = get_tmp_dir();
+ database_last_component_name = g_strdup_printf("db-%d", data->n_records);
+ database_path = g_build_filename(tmp_dir,
+ "between-sequential",
+ database_last_component_name,
+ NULL);
+ g_free(database_last_component_name);
+
+ if (g_file_test(database_path, G_FILE_TEST_EXISTS)) {
+ data->database = grn_db_open(context, database_path);
+ run_command(context, "dump");
+ } else {
+ data->database = grn_db_create(context, database_path, NULL);
+
+ run_command(context, "table_create Entries TABLE_NO_KEY");
+ run_command(context, "column_create Entries rank COLUMN_SCALAR Int32");
+
+ run_command(context, "load --table Entries");
+ run_command(context, "[");
+ for (i = 0; i < data->n_records; i++) {
+#define BUFFER_SIZE 4096
+ gchar buffer[BUFFER_SIZE];
+ const gchar *separator;
+ if (i == (data->n_records - 1)) {
+ separator = "";
+ } else {
+ separator = ",";
+ }
+ snprintf(buffer, BUFFER_SIZE, "{\"rank\": %u}%s", i, separator);
+ run_command(context, buffer);
+#undef BUFFER_SIZE
+ }
+ run_command(context, "]");
+ }
+
+ g_free(database_path);
+}
+
+static void
+bench_startup(BenchmarkData *data)
+{
+ grn_ctx_init(&(data->context), 0);
+ setup_database(data);
+}
+
+static void
+bench_shutdown(BenchmarkData *data)
+{
+ grn_ctx *context = &(data->context);
+
+ grn_obj_close(context, data->database);
+ grn_ctx_fin(context);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchReporter *reporter;
+ gint n = 10;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+
+ g_print("Process %d times in each pattern\n", n);
+
+ bench_init(&argc, &argv);
+ reporter = bench_reporter_new();
+
+ {
+ BenchmarkData data_small_between;
+ BenchmarkData data_small_range;
+ BenchmarkData data_medium_between;
+ BenchmarkData data_medium_range;
+ BenchmarkData data_large_between;
+ BenchmarkData data_large_range;
+ BenchmarkData data_very_large_between;
+ BenchmarkData data_very_large_range;
+
+#define REGISTER(data, n_records_, min, max, is_between) \
+ do { \
+ gchar *label; \
+ label = \
+ g_strdup_printf("(%6d, %6d] (%7d): %7s", \
+ min, max, n_records_, \
+ is_between ? "between" : "range"); \
+ data.n_records = n_records_; \
+ if (is_between) { \
+ data.command = \
+ "select Entries --cache no " \
+ "--filter " \
+ "'between(rank, " #min ", \"exclude\"," \
+ " " #max ", \"include\")'"; \
+ } else { \
+ data.command = \
+ "select Entries --cache no " \
+ "--filter 'rank > " #min " && rank <= " #max "'"; \
+ } \
+ bench_startup(&data); \
+ bench_reporter_register(reporter, label, \
+ n, \
+ NULL, \
+ bench, \
+ NULL, \
+ &data); \
+ g_free(label); \
+ } while(FALSE)
+
+ REGISTER(data_small_between,
+ 1000,
+ 500, 600,
+ TRUE);
+ REGISTER(data_small_range,
+ 1000,
+ 500, 600,
+ FALSE);
+ REGISTER(data_medium_between,
+ 10000,
+ 5000, 5100,
+ TRUE);
+ REGISTER(data_medium_range,
+ 10000,
+ 5000, 5100,
+ FALSE);
+ REGISTER(data_large_between,
+ 100000,
+ 50000, 50100,
+ TRUE);
+ REGISTER(data_large_range,
+ 100000,
+ 50000, 50100,
+ FALSE);
+ REGISTER(data_very_large_between,
+ 1000000,
+ 500000, 500100,
+ TRUE);
+ REGISTER(data_very_large_range,
+ 1000000,
+ 500000, 500100,
+ FALSE);
+
+#undef REGISTER
+
+ bench_reporter_run(reporter);
+
+ bench_shutdown(&data_small_between);
+ bench_shutdown(&data_small_range);
+ bench_shutdown(&data_medium_between);
+ bench_shutdown(&data_medium_range);
+ bench_shutdown(&data_large_between);
+ bench_shutdown(&data_large_range);
+ bench_shutdown(&data_very_large_between);
+ bench_shutdown(&data_very_large_range);
+ }
+ g_object_unref(reporter);
+
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-cache.c b/storage/mroonga/vendor/groonga/benchmark/bench-cache.c
new file mode 100644
index 00000000..104a7c19
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-cache.c
@@ -0,0 +1,155 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2017 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+/*
+ Groonga: eb65125330b3a8f920693ef3ad53011c7412f2c9
+ CFLAGS: -O2 -g3
+ CPU: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
+
+ % make --silent -C benchmark run-bench-cache
+ run-bench-cache:
+ (total) (average) (median)
+ 1000: (0.0458s) (0.4576ms) (0.4170ms)
+ 10000: (0.3464s) (0.0035s) (0.0034s)
+ % GRN_CACHE_TYPE=persistent make --silent -C benchmark run-bench-cache
+ run-bench-cache:
+ (total) (average) (median)
+ 1000: (0.0480s) (0.4801ms) (0.4700ms)
+ 10000: (0.4033s) (0.0040s) (0.0040s)
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <grn_cache.h>
+
+#include "lib/benchmark.h"
+
+typedef struct _BenchmarkData
+{
+ grn_ctx *context;
+ grn_cache *cache;
+ grn_obj value;
+} BenchmarkData;
+
+static void
+bench_n(BenchmarkData *data, gint64 n)
+{
+ gint64 i;
+ grn_ctx *ctx;
+ grn_cache *cache;
+ grn_obj *value;
+ grn_obj fetch_buffer;
+
+ ctx = data->context;
+ cache = data->cache;
+ value = &(data->value);
+ GRN_TEXT_INIT(&fetch_buffer, 0);
+ for (i = 0; i < n; i++) {
+ char key[GRN_TABLE_MAX_KEY_SIZE];
+ grn_snprintf(key,
+ GRN_TABLE_MAX_KEY_SIZE,
+ GRN_TABLE_MAX_KEY_SIZE,
+ "key:%" GRN_FMT_INT64D,
+ i);
+ GRN_BULK_REWIND(&fetch_buffer);
+ grn_cache_fetch(ctx, cache, key, strlen(key), &fetch_buffer);
+ grn_cache_update(ctx, cache, key, strlen(key), value);
+ }
+ GRN_OBJ_FIN(ctx, &fetch_buffer);
+}
+
+static void
+bench_1000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 1000);
+}
+
+static void
+bench_10000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 10000);
+}
+
+static void
+bench_setup(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ data->cache = grn_cache_open(data->context);
+ GRN_TEXT_INIT(&(data->value), 0);
+ while (GRN_TEXT_LEN(&(data->value)) < 1024) {
+ GRN_TEXT_PUTS(data->context, &(data->value), "XXXXXXXXXXX");
+ }
+}
+
+static void
+bench_teardown(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_obj_close(data->context, &(data->value));
+ grn_cache_close(data->context, data->cache);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchmarkData data;
+ BenchReporter *reporter;
+ gchar *base_dir;
+ grn_ctx ctx;
+ gint n = 100;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ grn_ctx_init(&ctx, 0);
+
+ data.context = &ctx;
+
+ base_dir = g_build_filename(g_get_tmp_dir(), "groonga-bench", NULL);
+ bench_utils_remove_path_recursive_force(base_dir);
+ g_mkdir_with_parents(base_dir, 0755);
+
+ reporter = bench_reporter_new();
+ bench_reporter_register(reporter, "1000", n,
+ bench_setup, bench_1000, bench_teardown, &data);
+ bench_reporter_register(reporter, "10000", n,
+ bench_setup, bench_10000, bench_teardown, &data);
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ grn_ctx_fin(&ctx);
+
+ bench_utils_remove_path_recursive_force(base_dir);
+
+ bench_quit();
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c b/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c
new file mode 100644
index 00000000..576ac8ee
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-ctx-create.c
@@ -0,0 +1,198 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2013-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+/*
+ Groonga: 6b128f318d682e50648f3b82c5f7956f3bcb3fe8
+ CFLAGS: -O0 -g3
+ % (cd benchmark/ && make --quiet run-bench-ctx-create)
+ run-bench-ctx-create:
+ (time)
+ with mruby1: 288KB (0.0091s)
+ without mruby1: 28KB (0.0240ms)
+ with mruby2: 0KB (0.0097s)
+ without mruby2: 0KB (0.0220ms)
+
+ Groonga: c4379140c02699e3c74b94cd9e7b88d372202aa5
+ CFLAGS: -O2 -g
+ % make --quiet -C benchmark run-bench-ctx-create
+ run-bench-ctx-create:
+ (time)
+ with mruby1: 524KB (0.0041s)
+ without mruby1: 32KB (0.0220ms)
+ with mruby2: 0KB (0.0040s)
+ without mruby2: 0KB (0.0200ms)
+*/
+
+#include <stdlib.h>
+
+#include <glib.h>
+
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+typedef struct _BenchmarkData {
+ grn_ctx context;
+ grn_obj *database;
+ guint memory_usage_before;
+} BenchmarkData;
+
+static guint
+get_memory_usage(void)
+{
+ GRegex *vm_rss_pattern;
+ gchar *status;
+ GMatchInfo *match_info;
+ gchar *vm_rss_string;
+ guint vm_rss;
+
+ g_file_get_contents("/proc/self/status", &status, NULL, NULL);
+
+ vm_rss_pattern = g_regex_new("VmRSS:\\s*(\\d*)\\s+kB", 0, 0, NULL);
+ if (!g_regex_match(vm_rss_pattern, status, 0, &match_info)) {
+ g_print("not match...: %s\n", status);
+ return 0;
+ }
+ vm_rss_string = g_match_info_fetch(match_info, 1);
+ vm_rss = atoi(vm_rss_string);
+ g_free(vm_rss_string);
+ g_match_info_free(match_info);
+ g_regex_unref(vm_rss_pattern);
+ g_free(status);
+
+ return vm_rss;
+}
+
+static void
+bench_with_mruby(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ g_setenv("GRN_MRUBY_ENABLED", "yes", TRUE);
+ grn_ctx_init(&(data->context), 0);
+ grn_ctx_use(&(data->context), data->database);
+}
+
+static void
+bench_without_mruby(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ g_setenv("GRN_MRUBY_ENABLED", "no", TRUE);
+ grn_ctx_init(&(data->context), 0);
+ grn_ctx_use(&(data->context), data->database);
+}
+
+static void
+bench_setup(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ data->memory_usage_before = get_memory_usage();
+}
+
+static void
+bench_teardown(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_ctx_fin(&(data->context));
+ g_print("%3dKB ", get_memory_usage() - data->memory_usage_before);
+}
+
+static gchar *
+get_tmp_dir(void)
+{
+ gchar *current_dir;
+ gchar *tmp_dir;
+
+ current_dir = g_get_current_dir();
+ tmp_dir = g_build_filename(current_dir, "tmp", NULL);
+ g_free(current_dir);
+
+ return tmp_dir;
+}
+
+static grn_obj *
+setup_database(grn_ctx *context)
+{
+ gchar *tmp_dir;
+ gchar *database_path;
+ grn_obj *database;
+
+ tmp_dir = get_tmp_dir();
+ database_path = g_build_filename(tmp_dir, "ctx-create", "db", NULL);
+ database = grn_db_open(context, database_path);
+
+ g_free(database_path);
+
+ return database;
+}
+
+static void
+teardown_database(grn_ctx *context, grn_obj *database)
+{
+ grn_obj_close(context, database);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ grn_ctx context;
+ BenchmarkData data;
+ BenchReporter *reporter;
+ gint n = 1;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ grn_ctx_init(&context, 0);
+
+ data.database = setup_database(&context);
+
+ reporter = bench_reporter_new();
+
+#define REGISTER(label, bench_function) \
+ bench_reporter_register(reporter, label, n, \
+ bench_setup, \
+ bench_function, \
+ bench_teardown, \
+ &data)
+ REGISTER("with mruby1", bench_with_mruby);
+ REGISTER("without mruby1", bench_without_mruby);
+ REGISTER("with mruby2", bench_with_mruby);
+ REGISTER("without mruby2", bench_without_mruby);
+#undef REGISTER
+
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ teardown_database(&context, data.database);
+
+ grn_ctx_fin(&context);
+
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c b/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c
new file mode 100644
index 00000000..0b648a1c
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-distance.c
@@ -0,0 +1,506 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2009-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+/*
+ groonga: 3ad91b868909444f66a36dbcbdbe2292ed14bd72
+ CFLAGS: -O0 -g
+ CPU: AMD Athlon(tm) 64 Processor 3000+
+
+ % test/benchmark/bench-geo-distance
+ (time)
+ rectangular (WGS84): (0.0813662)
+ rectangular (TOKYO): (0.0621928)
+ spherical (WGS84): (0.0760155)
+ spherical (TOKYO): (0.0660843)
+ hubeny (WGS84): (0.110684)
+ hubeny (TOKYO): (0.0702277)
+ % test/benchmark/bench-geo-distance
+ (time)
+ rectangular (WGS84): (0.0742154)
+ rectangular (TOKYO): (0.0816863)
+ spherical (WGS84): (0.074316)
+ spherical (TOKYO): (0.0696254)
+ hubeny (WGS84): (0.0650147)
+ hubeny (TOKYO): (0.0644057)
+ % test/benchmark/bench-geo-distance
+ (time)
+ rectangular (WGS84): (0.0781161)
+ rectangular (TOKYO): (0.0706679)
+ spherical (WGS84): (0.075739)
+ spherical (TOKYO): (0.0809402)
+ hubeny (WGS84): (0.0727023)
+ hubeny (TOKYO): (0.0718146)
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <grn_db.h>
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+#define GET(context, name) (grn_ctx_get(context, name, strlen(name)))
+
+grn_obj *grn_expr_get_value(grn_ctx *ctx, grn_obj *expr, int offset);
+
+typedef struct _BenchmarkData
+{
+ gchar *base_dir;
+ gboolean report_result;
+
+ grn_ctx *context;
+ grn_obj *database;
+ grn_obj *geo_distance_proc;
+ grn_obj *expression;
+ grn_obj *start_point;
+ grn_obj *end_point;
+} BenchmarkData;
+
+static void
+bench_geo_distance(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_proc_call(data->context, data->geo_distance_proc,
+ 2, data->expression);
+}
+
+static void
+bench_setup_common(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_ctx_init(data->context, GRN_CTX_USE_QL);
+ data->database = grn_db_create(data->context, NULL, NULL);
+ data->expression = grn_expr_create(data->context, NULL, 0);
+}
+
+static void
+bench_setup_points(gpointer user_data,
+ const gchar *start_point_string,
+ const gchar *end_point_string,
+ grn_builtin_type wgs84_or_tgs)
+{
+ BenchmarkData *data = user_data;
+ grn_obj start_point_text, end_point_text;
+
+ GRN_TEXT_INIT(&start_point_text, 0);
+ GRN_TEXT_INIT(&end_point_text, 0);
+ GRN_TEXT_SETS(data->context, &start_point_text, start_point_string);
+ GRN_TEXT_SETS(data->context, &end_point_text, end_point_string);
+
+ data->start_point = grn_obj_open(data->context, GRN_BULK, 0, wgs84_or_tgs);
+ data->end_point = grn_obj_open(data->context, GRN_BULK, 0, wgs84_or_tgs);
+ grn_obj_cast(data->context, &start_point_text, data->start_point, GRN_FALSE);
+ grn_obj_cast(data->context, &end_point_text, data->end_point, GRN_FALSE);
+ grn_ctx_push(data->context, data->start_point);
+ grn_ctx_push(data->context, data->end_point);
+
+ grn_obj_unlink(data->context, &start_point_text);
+ grn_obj_unlink(data->context, &end_point_text);
+}
+
+static void
+bench_setup_wgs84(gpointer user_data)
+{
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "127980000x502560000",
+ "128880000x503640000",
+ GRN_DB_WGS84_GEO_POINT);
+}
+
+static void
+bench_setup_tgs(gpointer user_data)
+{
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "127980000x502560000",
+ "128880000x503640000",
+ GRN_DB_TOKYO_GEO_POINT);
+}
+
+static void
+bench_setup_rectangular_wgs84(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_wgs84(user_data);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_tgs(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_tgs(user_data);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_1st_to_2nd_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "128452975x503157902",
+ "139380000x-31920000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_2nd_to_1st_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "139380000x-31920000",
+ "128452975x503157902",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_1st_to_3rd_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "128452975x503157902",
+ "-56880000x-172310000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_3rd_to_1st_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "-56880000x-172310000",
+ "128452975x503157902",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_1st_to_4th_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "128452975x503157902",
+ "-122100000x66300000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_4th_to_1st_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "-122100000x66300000",
+ "128452975x503157902",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_2nd_to_4th_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "139380000x-31920000",
+ "-122100000x66300000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_4th_to_2nd_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "-122100000x66300000",
+ "139380000x-31920000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_1st_to_2nd_quadrant_long(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "128452975x503157902",
+ "135960000x-440760000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_2nd_to_1st_quadrant_long(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "135960000x-440760000",
+ "128452975x503157902",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_2nd_to_3rd_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "135960000x-440760000",
+ "-56880000x-172310000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_3rd_to_2nd_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "-56880000x-172310000",
+ "135960000x-440760000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_3rd_to_4th_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "-56880000x-172310000",
+ "-122100000x66300000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_4th_to_3rd_quadrant_short(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "-122100000x66300000",
+ "-56880000x-172310000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_3rd_to_4th_quadrant_long(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "-56880000x-172310000",
+ "-121926000x544351000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_rectangular_wgs84_4th_to_3rd_quadrant_long(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_common(user_data);
+ bench_setup_points(user_data,
+ "-121926000x544351000",
+ "-56880000x-172310000",
+ GRN_DB_WGS84_GEO_POINT);
+ data->geo_distance_proc = GET(data->context, "geo_distance");
+}
+
+static void
+bench_setup_spherical_wgs84(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_wgs84(user_data);
+ data->geo_distance_proc = GET(data->context, "geo_distance2");
+}
+
+static void
+bench_setup_spherical_tgs(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_tgs(user_data);
+ data->geo_distance_proc = GET(data->context, "geo_distance2");
+}
+
+static void
+bench_setup_hubeny_wgs84(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_wgs84(user_data);
+ data->geo_distance_proc = GET(data->context, "geo_distance3");
+}
+
+static void
+bench_setup_hubeny_tgs(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ bench_setup_tgs(user_data);
+ data->geo_distance_proc = GET(data->context, "geo_distance3");
+}
+
+static void
+bench_teardown(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ if (data->report_result) {
+ grn_obj *result;
+ result = grn_expr_get_value(data->context, data->expression, 0);
+ g_print("result: %g\n", GRN_FLOAT_VALUE(result));
+ /* http://vldb.gsi.go.jp/ says '38820.79' in WGS84 and
+ '38816.42' in Tokyo geodetic system for a distance
+ between '127980000x502560000' and '128880000x503640000'. */
+ }
+
+ grn_obj_unlink(data->context, data->end_point);
+ grn_obj_unlink(data->context, data->start_point);
+ grn_obj_unlink(data->context, data->expression);
+ grn_obj_unlink(data->context, data->database);
+ grn_ctx_fin(data->context);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchmarkData data;
+ BenchReporter *reporter;
+ gint n = 1000;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ data.report_result = g_getenv("GROONGA_BENCH_REPORT_RESULT") != NULL;
+ data.context = g_new(grn_ctx, 1);
+
+ {
+ const gchar *groonga_bench_n;
+ groonga_bench_n = g_getenv("GROONGA_BENCH_N");
+ if (groonga_bench_n) {
+ n = atoi(groonga_bench_n);
+ }
+ }
+
+ reporter = bench_reporter_new();
+
+#define REGISTER(label, setup) \
+ bench_reporter_register(reporter, label, n, \
+ bench_setup_ ## setup, \
+ bench_geo_distance, \
+ bench_teardown, \
+ &data)
+ REGISTER("rectangular (WGS84)", rectangular_wgs84);
+ REGISTER("rectangular (TOKYO)", rectangular_tgs);
+ REGISTER("rectangular (WGS84 Tokyo to Lisbon)",
+ rectangular_wgs84_1st_to_2nd_quadrant_short);
+ REGISTER("rectangular (WGS84 Lisbon to Tokyo)",
+ rectangular_wgs84_2nd_to_1st_quadrant_short);
+ REGISTER("rectangular (WGS84 Tokyo to San Francisco)",
+ rectangular_wgs84_1st_to_2nd_quadrant_long);
+ REGISTER("rectangular (WGS84 San Francisco to Tokyo)",
+ rectangular_wgs84_2nd_to_1st_quadrant_long);
+ REGISTER("rectangular (WGS84 Brasplia to Cape Town)",
+ rectangular_wgs84_3rd_to_4th_quadrant_short);
+ REGISTER("rectangular (WGS84 Cape Town to Brasplia)",
+ rectangular_wgs84_4th_to_3rd_quadrant_short);
+ REGISTER("rectangular (WGS84 Brasplia to Sydney)",
+ rectangular_wgs84_3rd_to_4th_quadrant_long);
+ REGISTER("rectangular (WGS84 Sydney to Brasplia)",
+ rectangular_wgs84_4th_to_3rd_quadrant_long);
+ REGISTER("rectangular (WGS84 Tokyo to Brasplia)",
+ rectangular_wgs84_1st_to_4th_quadrant_short);
+ REGISTER("rectangular (WGS84 Brasplia to Tokyo)",
+ rectangular_wgs84_4th_to_1st_quadrant_short);
+ REGISTER("rectangular (WGS84 Lisbon to Cape Town)",
+ rectangular_wgs84_2nd_to_3rd_quadrant_short);
+ REGISTER("rectangular (WGS84 Cape Town to Lisbon)",
+ rectangular_wgs84_3rd_to_2nd_quadrant_short);
+ REGISTER("rectangular (WGS84 Tokyo to Cape Town)",
+ rectangular_wgs84_1st_to_3rd_quadrant_short);
+ REGISTER("rectangular (WGS84 Cape Town to Tokyo)",
+ rectangular_wgs84_3rd_to_1st_quadrant_short);
+ REGISTER("rectangular (WGS84 Lisbon to Cape Town)",
+ rectangular_wgs84_2nd_to_4th_quadrant_short);
+ REGISTER("rectangular (WGS84 Cape Town to Lisbon)",
+ rectangular_wgs84_4th_to_2nd_quadrant_short);
+ REGISTER("spherical (WGS84)", spherical_wgs84);
+ REGISTER("spherical (TOKYO)", spherical_tgs);
+ REGISTER("hubeny (WGS84)", hubeny_wgs84);
+ REGISTER("hubeny (TOKYO)", hubeny_tgs);
+#undef REGISTER
+
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ g_free(data.context);
+
+ bench_quit();
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c
new file mode 100644
index 00000000..dcad47fd
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.c
@@ -0,0 +1,276 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2011-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+/*
+ groonga: f56f466a05d756336f26ea5c2e54e9bdf5d3d681
+ CFLAGS: -O0 -ggdb3
+ CPU: Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz stepping 05
+ % (cd test/benchmark/ && make --quiet run-bench-geo-select)
+ run-bench-geo-select:
+ (time)
+ 1st: select_in_rectangle (partial): (0.819828)
+ 2nd: select_in_rectangle (partial): (0.832293)
+ 1st: select_in_rectangle (all): (8.82504)
+ 2nd: select_in_rectangle (all): (8.97628)
+
+ % (cd test/benchmark; GRN_GEO_CURSOR_STRICTLY=yes make --quiet run-bench-geo-select)
+ run-bench-geo-select:
+ (time)
+ 1st: select_in_rectangle (partial): (0.528143)
+ 2nd: select_in_rectangle (partial): (0.518647)
+ 1st: select_in_rectangle (all): (8.77378)
+ 2nd: select_in_rectangle (all): (8.76765)
+
+ groonga: f56f466a05d756336f26ea5c2e54e9bdf5d3d681
+ CFLAGS: -O3 -ggdb3
+ CPU: Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz stepping 05
+ % (cd test/benchmark/ && make --quiet run-bench-geo-select)
+ run-bench-geo-select:
+ (time)
+ 1st: select_in_rectangle (partial): (0.415439)
+ 2nd: select_in_rectangle (partial): (0.423479)
+ 1st: select_in_rectangle (all): (4.63983)
+ 2nd: select_in_rectangle (all): (4.53055)
+
+ % (cd test/benchmark; GRN_GEO_CURSOR_STRICTLY=yes make --quiet run-bench-geo-select)
+ run-bench-geo-select:
+ (time)
+ 1st: select_in_rectangle (partial): (0.26974)
+ 2nd: select_in_rectangle (partial): (0.250247)
+ 1st: select_in_rectangle (all): (4.45263)
+ 2nd: select_in_rectangle (all): (4.61558)
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <grn_db.h>
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+#define GET(context, name) (grn_ctx_get(context, name, strlen(name)))
+
+typedef struct _BenchmarkData
+{
+ gboolean report_result;
+
+ grn_ctx *context;
+ grn_obj *database;
+ grn_obj *table;
+ grn_obj *index_column;
+ grn_obj *result;
+
+ grn_obj top_left_point;
+ grn_obj bottom_right_point;
+} BenchmarkData;
+
+static void
+set_geo_point(grn_ctx *context, grn_obj *geo_point, const gchar *geo_point_text)
+{
+ grn_obj point_text;
+
+ GRN_TEXT_INIT(&point_text, 0);
+ GRN_TEXT_PUTS(context, &point_text, geo_point_text);
+ grn_obj_cast(context, &point_text, geo_point, GRN_FALSE);
+ grn_obj_unlink(context, &point_text);
+}
+
+static void
+bench_setup_common(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ const gchar *tokyo_station = "35.68136,139.76609";
+ const gchar *ikebukuro_station = "35.72890,139.71036";
+
+ data->result = grn_table_create(data->context, NULL, 0, NULL,
+ GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
+ data->table, NULL);
+
+ set_geo_point(data->context, &(data->top_left_point),
+ ikebukuro_station);
+ set_geo_point(data->context, &(data->bottom_right_point),
+ tokyo_station);
+}
+
+static void
+bench_setup_query_partial(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ const gchar *tokyo_station = "35.68136,139.76609";
+ const gchar *ikebukuro_station = "35.72890,139.71036";
+
+ set_geo_point(data->context, &(data->top_left_point),
+ ikebukuro_station);
+ set_geo_point(data->context, &(data->bottom_right_point),
+ tokyo_station);
+}
+
+static void
+bench_setup_query_all(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ const gchar *tokyo_station = "35.0,140.0";
+ const gchar *ikebukuro_station = "36.0,139.0";
+
+ set_geo_point(data->context, &(data->top_left_point),
+ ikebukuro_station);
+ set_geo_point(data->context, &(data->bottom_right_point),
+ tokyo_station);
+}
+
+static void
+bench_setup_in_rectangle_partial(gpointer user_data)
+{
+ bench_setup_common(user_data);
+ bench_setup_query_partial(user_data);
+}
+
+static void
+bench_setup_in_rectangle_all(gpointer user_data)
+{
+ bench_setup_common(user_data);
+ bench_setup_query_all(user_data);
+}
+
+static void
+bench_geo_select_in_rectangle(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_geo_select_in_rectangle(data->context,
+ data->index_column,
+ &(data->top_left_point),
+ &(data->bottom_right_point),
+ data->result,
+ GRN_OP_OR);
+}
+
+static void
+bench_teardown(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ if (data->report_result) {
+ g_print("result: %d\n", grn_table_size(data->context, data->result));
+ }
+
+ grn_obj_unlink(data->context, data->result);
+}
+
+static gchar *
+get_tmp_dir(void)
+{
+ gchar *current_dir;
+ gchar *tmp_dir;
+
+ current_dir = g_get_current_dir();
+ tmp_dir = g_build_filename(current_dir, "tmp", NULL);
+ g_free(current_dir);
+
+ return tmp_dir;
+}
+
+static void
+setup_database(BenchmarkData *data)
+{
+ gchar *tmp_dir;
+ gchar *database_path;
+
+ tmp_dir = get_tmp_dir();
+ database_path = g_build_filename(tmp_dir, "geo-select", "db", NULL);
+ data->database = grn_db_open(data->context, database_path);
+
+ data->table = GET(data->context, "Addresses");
+ data->index_column = GET(data->context, "Locations.address");
+
+ g_free(database_path);
+}
+
+static void
+teardown_database(BenchmarkData *data)
+{
+ grn_obj_unlink(data->context, data->index_column);
+ grn_obj_unlink(data->context, data->table);
+ grn_obj_unlink(data->context, data->database);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchmarkData data;
+ BenchReporter *reporter;
+ gint n = 100;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ data.report_result = g_getenv("GROONGA_BENCH_REPORT_RESULT") != NULL;
+
+ data.context = g_new(grn_ctx, 1);
+ grn_ctx_init(data.context, 0);
+
+ setup_database(&data);
+ GRN_WGS84_GEO_POINT_INIT(&(data.top_left_point), 0);
+ GRN_WGS84_GEO_POINT_INIT(&(data.bottom_right_point), 0);
+
+ {
+ const gchar *groonga_bench_n;
+ groonga_bench_n = g_getenv("GROONGA_BENCH_N");
+ if (groonga_bench_n) {
+ n = atoi(groonga_bench_n);
+ }
+ }
+
+ reporter = bench_reporter_new();
+
+#define REGISTER(label, type, area) \
+ bench_reporter_register(reporter, \
+ label, \
+ n, \
+ bench_setup_ ## type ## _ ## area, \
+ bench_geo_select_ ## type, \
+ bench_teardown, \
+ &data)
+ REGISTER("1st: select_in_rectangle (partial)", in_rectangle, partial);
+ REGISTER("2nd: select_in_rectangle (partial)", in_rectangle, partial);
+ REGISTER("1st: select_in_rectangle (all)", in_rectangle, all);
+ REGISTER("2nd: select_in_rectangle (all)", in_rectangle, all);
+#undef REGISTER
+
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ grn_obj_unlink(data.context, &(data.top_left_point));
+ grn_obj_unlink(data.context, &(data.bottom_right_point));
+ teardown_database(&data);
+
+ grn_ctx_fin(data.context);
+ g_free(data.context);
+
+ bench_quit();
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.sh b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.sh
new file mode 100755
index 00000000..7e84c8fc
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-geo-select.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+base_dir="$(dirname $0)"
+
+fixture_dir="${srcdir}/fixtures/geo-select"
+data_dir="${base_dir}/fixtures/geo-select"
+csv_xz="${fixture_dir}/13_2010.CSV.xz"
+csv="${data_dir}/13_2010.CSV"
+grn="${data_dir}/load.grn"
+
+geo_select_generate_grn_rb="${base_dir}/geo-select-generate-grn.rb"
+
+db="${base_dir}/tmp/geo-select/db"
+
+bench_geo_select="./bench-geo-select"
+
+mkdir -p "${data_dir}"
+if [ ! -s "${csv}" ] || [ "${csv}" -ot "${csv_xz}" ]; then
+ echo "extracting ${csv_xz}..."
+ xzcat "${csv_xz}" | iconv --from-code cp932 --to-code utf-8 > "${csv}"
+fi
+
+if [ ! -s "${grn}" ] || [ "${grn}" -ot "${csv}" ]; then
+ echo "generating test data..."
+ "${RUBY}" "${geo_select_generate_grn_rb}" "${csv}" "${grn}"
+fi
+
+if [ ! -s "${db}" ] || [ "${db}" -ot "${grn}" ]; then
+ echo "creating test database..."
+ rm -rf "$(dirname ${db})"
+ mkdir -p "$(dirname ${db})"
+ "${GROONGA}" -n "${db}" < "${grn}"
+fi
+
+if [ "${GROONGA_BENCH_DEBUG}" = "yes" ]; then
+ bench_geo_select="../../libtool --mode=execute gdb --args ${bench_geo_select}"
+fi
+${bench_geo_select}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c b/storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c
new file mode 100644
index 00000000..ebae95b2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-nfkc.c
@@ -0,0 +1,275 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+/*
+ Groonga: ed300a833d44eaefa978b5ecf46a96ef91ae0891
+
+ CFLAGS: -O2 -g
+ % make --quiet -C benchmark run-bench-nfkc
+ run-bench-nfkc:
+ (total) (average) (median)
+ map1 - switch : (0.0060ms) (0.00060000ms) (0.00000000ms)
+ map1 - table : (0.00000000ms) (0.00000000ms) (0.00000000ms)
+ map2 - switch - no change: (0.0010ms) (0.00010000ms) (0.00000000ms)
+ map2 - table - no change: (0.00000000ms) (0.00000000ms) (0.00000000ms)
+ map2 - switch - change: (0.0010ms) (0.00010000ms) (0.00000000ms)
+ map2 - table - change: (0.0010ms) (0.00010000ms) (0.00000000ms)
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+#include "../lib/nfkc50.c"
+
+#define MAX_UNICODE 0x110000
+#define BUFFER_SIZE 0x100
+
+static inline int
+ucs2utf8(unsigned int i, unsigned char *buf)
+{
+ unsigned char *p = buf;
+ if (i < 0x80) {
+ *p++ = i;
+ } else {
+ if (i < 0x800) {
+ *p++ = (i >> 6) | 0xc0;
+ } else {
+ if (i < 0x00010000) {
+ *p++ = (i >> 12) | 0xe0;
+ } else {
+ if (i < 0x00200000) {
+ *p++ = (i >> 18) | 0xf0;
+ } else {
+ if (i < 0x04000000) {
+ *p++ = (i >> 24) | 0xf8;
+ } else if (i < 0x80000000) {
+ *p++ = (i >> 30) | 0xfc;
+ *p++ = ((i >> 24) & 0x3f) | 0x80;
+ }
+ *p++ = ((i >> 18) & 0x3f) | 0x80;
+ }
+ *p++ = ((i >> 12) & 0x3f) | 0x80;
+ }
+ *p++ = ((i >> 6) & 0x3f) | 0x80;
+ }
+ *p++ = (0x3f & i) | 0x80;
+ }
+ *p = '\0';
+ return (p - buf);
+}
+
+static void
+bench_char_type(gpointer user_data)
+{
+ uint64_t code_point;
+ char utf8[7];
+
+ for (code_point = 1; code_point < MAX_UNICODE; code_point++) {
+ ucs2utf8(code_point, (unsigned char *)utf8);
+ grn_nfkc50_char_type(utf8);
+ }
+}
+
+static void
+bench_decompose(gpointer user_data)
+{
+ uint64_t code_point;
+ char utf8[7];
+
+ for (code_point = 1; code_point < MAX_UNICODE; code_point++) {
+ ucs2utf8(code_point, (unsigned char *)utf8);
+ grn_nfkc50_decompose(utf8);
+ }
+}
+
+static void
+bench_compose_no_change(gpointer user_data)
+{
+ uint64_t prefix_code_point;
+ uint64_t suffix_code_point = 0x61; /* a */
+ char prefix_utf8[7];
+ char suffix_utf8[7];
+
+ ucs2utf8(suffix_code_point, (unsigned char *)suffix_utf8);
+ for (prefix_code_point = 1;
+ prefix_code_point < MAX_UNICODE;
+ prefix_code_point++) {
+ ucs2utf8(prefix_code_point, (unsigned char *)prefix_utf8);
+ grn_nfkc50_compose(prefix_utf8, suffix_utf8);
+ }
+}
+
+static void
+bench_compose_change(gpointer user_data)
+{
+ uint64_t prefix_code_point;
+ uint64_t suffix_code_point = 0x11ba;
+ char prefix_utf8[7];
+ char suffix_utf8[7];
+
+ ucs2utf8(suffix_code_point, (unsigned char *)suffix_utf8);
+ for (prefix_code_point = 1;
+ prefix_code_point < MAX_UNICODE;
+ prefix_code_point++) {
+ ucs2utf8(prefix_code_point, (unsigned char *)prefix_utf8);
+ grn_nfkc50_compose(prefix_utf8, suffix_utf8);
+ }
+}
+
+/*
+static void
+check_char_type(gpointer user_data)
+{
+ uint64_t code_point;
+ char utf8[7];
+
+ for (code_point = 1; code_point < MAX_UNICODE; code_point++) {
+ grn_char_type a;
+ grn_char_type b;
+
+ ucs2utf8(code_point, (unsigned char *)utf8);
+ a = grn_nfkc_char_type(utf8);
+ b = grn_nfkc50_char_type(utf8);
+ if (a == b) {
+ continue;
+ }
+ printf("%lx: %s: %d != %d\n", code_point, utf8, a, b);
+ }
+}
+
+static void
+check_decompose(gpointer user_data)
+{
+ uint64_t code_point;
+ char utf8[7];
+
+ for (code_point = 1; code_point < MAX_UNICODE; code_point++) {
+ const char *a;
+ const char *b;
+
+ ucs2utf8(code_point, (unsigned char *)utf8);
+ a = grn_nfkc_decompose(utf8);
+ b = grn_nfkc50_decompose(utf8);
+ if (a == b) {
+ continue;
+ }
+ if (!a || !b) {
+ printf("%lx: %s: %s != %s\n", code_point, utf8, a, b);
+ continue;
+ }
+ if (strcmp(a, b) != 0) {
+ printf("%lx: %s: %s != %s\n", code_point, utf8, a, b);
+ }
+ }
+}
+
+static void
+check_compose(gpointer user_data)
+{
+ uint64_t prefix_code_point;
+ uint64_t suffix_code_point;
+ char prefix_utf8[7];
+ char suffix_utf8[7];
+
+ for (prefix_code_point = 1;
+ prefix_code_point < MAX_UNICODE;
+ prefix_code_point++) {
+ ucs2utf8(prefix_code_point, (unsigned char *)prefix_utf8);
+ for (suffix_code_point = 1;
+ suffix_code_point < MAX_UNICODE;
+ suffix_code_point++) {
+ const char *a;
+ const char *b;
+
+ ucs2utf8(suffix_code_point, (unsigned char *)suffix_utf8);
+ a = grn_nfkc_compose(prefix_utf8, suffix_utf8);
+ b = grn_nfkc50_compose(prefix_utf8, suffix_utf8);
+ if (a == b) {
+ continue;
+ }
+ if (!a || !b) {
+ printf("%lx-%lx: %s-%s: %s != %s\n",
+ prefix_code_point, suffix_code_point,
+ prefix_utf8, suffix_utf8,
+ a, b);
+ continue;
+ }
+ if (strcmp(a, b) != 0) {
+ printf("%lx-%lx: %s-%s: %s != %s\n",
+ prefix_code_point, suffix_code_point,
+ prefix_utf8, suffix_utf8,
+ a, b);
+ }
+ }
+ if ((prefix_code_point % 10000) == 0) {
+ printf("%" G_GUINT64_FORMAT "\n", prefix_code_point);
+ }
+ }
+}
+*/
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchReporter *reporter;
+ gint n = 10;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ reporter = bench_reporter_new();
+
+ if (g_getenv("N")) {
+ n = atoi(g_getenv("N"));
+ }
+
+#define REGISTER(label, bench_function) \
+ bench_reporter_register(reporter, label, n, \
+ NULL, \
+ bench_function, \
+ NULL, \
+ NULL)
+ REGISTER("char_type ", bench_char_type);
+ REGISTER("decompose ", bench_decompose);
+ REGISTER("compose - no change", bench_compose_no_change);
+ REGISTER("compose - change", bench_compose_change);
+
+ /*
+ REGISTER("check - char_type", check_char_type);
+ REGISTER("check - decompose", check_decompose);
+ REGISTER("check - compose ", check_compose);
+ */
+#undef REGISTER
+
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer-ddl.grn b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer-ddl.grn
new file mode 100644
index 00000000..68317ae9
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer-ddl.grn
@@ -0,0 +1,16 @@
+table_create Entries TABLE_PAT_KEY ShortText
+column_create Entries name COLUMN_SCALAR ShortText
+column_create Entries description COLUMN_SCALAR Text
+column_create Entries last_modified COLUMN_SCALAR Time
+
+table_create Bigram TABLE_PAT_KEY ShortText \
+ --default_tokenizer TokenBigram \
+ --normalizer NormalizerAuto
+column_create Bigram entries_name COLUMN_INDEX|WITH_POSITION \
+ Entries name
+column_create Bigram entries_description COLUMN_INDEX|WITH_POSITION \
+ Entries description
+
+table_create Times TABLE_PAT_KEY Time
+column_create Times entries_last_modified COLUMN_INDEX \
+ Entries last_modified
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c
new file mode 100644
index 00000000..48c2cb0f
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-query-optimizer.c
@@ -0,0 +1,214 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2014-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+/*
+ Groonga: c4379140c02699e3c74b94cd9e7b88d372202aa5
+
+ CFLAGS: -O0 -g3
+ % make --quiet -C benchmark run-bench-query-optimizer
+ run-bench-query-optimizer:
+ Process 100 times in each pattern
+ (time)
+ 1 condition: with mruby: (0.0362s)
+ 1 condition: without mruby: (0.0216s)
+ 4 conditions: with mruby: (0.0864s)
+ 4 conditions: without mruby: (0.0271s)
+
+ CFLAGS: -O2 -g
+ % make --quiet -C benchmark run-bench-query-optimizer
+ run-bench-query-optimizer:
+ Process 100 times in each pattern
+ (time)
+ 1 condition: with mruby: (0.0243s)
+ 1 condition: without mruby: (0.0159s)
+ 4 conditions: with mruby: (0.0452s)
+ 4 conditions: without mruby: (0.0188s)
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+typedef struct _BenchmarkData {
+ grn_ctx context;
+ grn_obj *database;
+ grn_bool use_mruby;
+ GString *command;
+} BenchmarkData;
+
+static void
+bench(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ grn_ctx *context = &(data->context);
+ char *response;
+ unsigned int response_length;
+ int flags;
+
+ grn_ctx_send(context, data->command->str, data->command->len, 0);
+ grn_ctx_recv(context, &response, &response_length, &flags);
+}
+
+static void
+bench_setup(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ if (data->use_mruby) {
+ g_setenv("GRN_MRUBY_ENABLED", "yes", TRUE);
+ } else {
+ g_setenv("GRN_MRUBY_ENABLED", "no", TRUE);
+ }
+ grn_ctx_init(&(data->context), 0);
+ grn_ctx_use(&(data->context), data->database);
+}
+
+static void
+bench_teardown(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_ctx_fin(&(data->context));
+}
+
+static gchar *
+get_tmp_dir(void)
+{
+ gchar *current_dir;
+ gchar *tmp_dir;
+
+ current_dir = g_get_current_dir();
+ tmp_dir = g_build_filename(current_dir, "tmp", NULL);
+ g_free(current_dir);
+
+ return tmp_dir;
+}
+
+static grn_obj *
+setup_database(grn_ctx *context)
+{
+ gchar *tmp_dir;
+ gchar *database_path;
+ grn_obj *database;
+ const gchar *warmup_command = "dump";
+ gchar *response;
+ unsigned int response_length;
+ int flags;
+
+ tmp_dir = get_tmp_dir();
+ database_path = g_build_filename(tmp_dir, "query-optimizer", "db", NULL);
+ database = grn_db_open(context, database_path);
+ grn_ctx_send(context, warmup_command, strlen(warmup_command), 0);
+ grn_ctx_recv(context, &response, &response_length, &flags);
+
+ g_free(database_path);
+
+ return database;
+}
+
+static void
+teardown_database(grn_ctx *context, grn_obj *database)
+{
+ grn_obj_close(context, database);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ grn_ctx context;
+ grn_obj *database;
+ BenchReporter *reporter;
+ gint n = 100;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ grn_ctx_init(&context, 0);
+
+ database = setup_database(&context);
+
+ reporter = bench_reporter_new();
+
+ g_print("Process %d times in each pattern\n", n);
+ {
+ BenchmarkData data_one_condition_with_mruby;
+ BenchmarkData data_one_condition_without_mruby;
+ BenchmarkData data_multiple_conditions_with_mruby;
+ BenchmarkData data_multiple_conditions_without_mruby;
+
+#define REGISTER(label, data, use_mruby_, command_) \
+ data.database = database; \
+ data.use_mruby = use_mruby_; \
+ data.command = g_string_new(command_); \
+ bench_reporter_register(reporter, label, \
+ n, \
+ bench_setup, \
+ bench, \
+ bench_teardown, \
+ &data)
+
+ REGISTER("1 condition: with mruby", data_one_condition_with_mruby,
+ GRN_TRUE,
+ "select Entries --cache no --query 'name:@Groonga'");
+ REGISTER("1 condition: without mruby", data_one_condition_without_mruby,
+ GRN_FALSE,
+ "select Entries --cache no --query 'name:@Groonga'");
+ REGISTER("4 conditions: with mruby",
+ data_multiple_conditions_with_mruby,
+ GRN_TRUE,
+ "select Entries --cache no --filter '"
+ "name @ \"Groonga\" && "
+ "description @ \"search\" && "
+ "last_modified >= \"2014-2-9 00:00:00\" && "
+ "last_modified <= \"2014-11-29 00:00:00\""
+ "'");
+ REGISTER("4 conditions: without mruby",
+ data_multiple_conditions_without_mruby,
+ GRN_FALSE,
+ "select Entries --cache no --filter '"
+ "name @ \"Groonga\" && "
+ "description @ \"search\" && "
+ "last_modified >= \"2014-2-9 00:00:00\" && "
+ "last_modified <= \"2014-11-29 00:00:00\""
+ "'");
+
+#undef REGISTER
+
+ bench_reporter_run(reporter);
+ }
+ g_object_unref(reporter);
+
+ teardown_database(&context, database);
+
+ grn_ctx_fin(&context);
+
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c b/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c
new file mode 100644
index 00000000..11df9c10
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-range-select.c
@@ -0,0 +1,280 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2014-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+/*
+ Groonga: 09a4c4e00832fb90dee74c5b97b7cf0f5952f85b
+
+ CPU Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz (fam: 06, model: 1e, stepping: 05)
+
+ CFLAGS: -O0 -g3
+ % make --quiet -C benchmark run-bench-range-select
+ run-bench-range-select:
+ Process 10 times in each pattern
+ (total) (average) (median)
+ ( 500, 600] ( 1000): with mruby: (0.0058s) (0.5773ms) (0.5830ms)
+ ( 500, 600] ( 1000): without mruby: (0.0062s) (0.6203ms) (0.6200ms)
+ ( 5000, 5100] ( 10000): with mruby: (0.0058s) (0.5827ms) (0.5800ms)
+ ( 5000, 5100] ( 10000): without mruby: (0.0473s) (0.0047s) (0.0048s)
+ ( 50000, 50100] ( 100000): with mruby: (0.0064s) (0.6397ms) (0.6370ms)
+ ( 50000, 50100] ( 100000): without mruby: (0.4498s) (0.0450s) (0.0442s)
+ (500000, 500100] (1000000): with mruby: (0.0057s) (0.5710ms) (0.5190ms)
+ (500000, 500100] (1000000): without mruby: (4.3193s) (0.4319s) (0.4306s)
+
+ CFLAGS: -O2 -g
+ % make --quiet -C benchmark run-bench-range-select
+ run-bench-range-select:
+ Process 10 times in each pattern
+ (total) (average) (median)
+ ( 500, 600] ( 1000): with mruby: (0.0031s) (0.3058ms) (0.2890ms)
+ ( 500, 600] ( 1000): without mruby: (0.0031s) (0.3132ms) (0.3090ms)
+ ( 5000, 5100] ( 10000): with mruby: (0.0031s) (0.3063ms) (0.3100ms)
+ ( 5000, 5100] ( 10000): without mruby: (0.0239s) (0.0024s) (0.0023s)
+ ( 50000, 50100] ( 100000): with mruby: (0.0028s) (0.2825ms) (0.2660ms)
+ ( 50000, 50100] ( 100000): without mruby: (0.2117s) (0.0212s) (0.0211s)
+ (500000, 500100] (1000000): with mruby: (0.0028s) (0.2757ms) (0.2650ms)
+ (500000, 500100] (1000000): without mruby: (2.0874s) (0.2087s) (0.2092s)
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grn_db.h>
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+#define GET(context, name) (grn_ctx_get(context, name, strlen(name)))
+
+typedef struct _BenchmarkData
+{
+ grn_ctx context;
+ grn_obj *database;
+ guint n_records;
+ grn_bool use_mruby;
+ const gchar *command;
+} BenchmarkData;
+
+static void
+run_command(grn_ctx *context, const gchar *command)
+{
+ gchar *response;
+ unsigned int response_length;
+ int flags;
+
+ grn_ctx_send(context, command, strlen(command), 0);
+ grn_ctx_recv(context, &response, &response_length, &flags);
+}
+
+static void
+bench(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ grn_ctx *context = &(data->context);
+
+ run_command(context, data->command);
+}
+
+static gchar *
+get_tmp_dir(void)
+{
+ gchar *current_dir;
+ gchar *tmp_dir;
+
+ current_dir = g_get_current_dir();
+ tmp_dir = g_build_filename(current_dir, "tmp", NULL);
+ g_free(current_dir);
+
+ return tmp_dir;
+}
+
+static void
+setup_database(BenchmarkData *data)
+{
+ grn_ctx *context = &(data->context);
+ gchar *tmp_dir;
+ gchar *database_last_component_name;
+ gchar *database_path;
+ guint i;
+
+ tmp_dir = get_tmp_dir();
+ database_last_component_name =
+ g_strdup_printf("db-%d-%s-mruby",
+ data->n_records,
+ data->use_mruby ? "with" : "without");
+ database_path = g_build_filename(tmp_dir,
+ "range-select",
+ database_last_component_name,
+ NULL);
+ g_free(database_last_component_name);
+
+ if (g_file_test(database_path, G_FILE_TEST_EXISTS)) {
+ data->database = grn_db_open(context, database_path);
+ run_command(context, "dump");
+ } else {
+ data->database = grn_db_create(context, database_path, NULL);
+
+ run_command(context, "table_create Entries TABLE_NO_KEY");
+ run_command(context, "column_create Entries rank COLUMN_SCALAR Int32");
+ run_command(context, "table_create Ranks TABLE_PAT_KEY Int32");
+ run_command(context,
+ "column_create Ranks entries_rank COLUMN_INDEX Entries rank");
+
+ run_command(context, "load --table Entries");
+ run_command(context, "[");
+ for (i = 0; i < data->n_records; i++) {
+#define BUFFER_SIZE 4096
+ gchar buffer[BUFFER_SIZE];
+ const gchar *separator;
+ if (i == (data->n_records - 1)) {
+ separator = "";
+ } else {
+ separator = ",";
+ }
+ snprintf(buffer, BUFFER_SIZE, "{\"rank\": %u}%s", i, separator);
+ run_command(context, buffer);
+#undef BUFFER_SIZE
+ }
+ run_command(context, "]");
+ }
+
+ g_free(database_path);
+}
+
+static void
+bench_startup(BenchmarkData *data)
+{
+ if (data->use_mruby) {
+ g_setenv("GRN_MRUBY_ENABLED", "yes", TRUE);
+ } else {
+ g_setenv("GRN_MRUBY_ENABLED", "no", TRUE);
+ }
+ grn_ctx_init(&(data->context), 0);
+ setup_database(data);
+}
+
+static void
+bench_shutdown(BenchmarkData *data)
+{
+ grn_ctx *context = &(data->context);
+
+ grn_obj_close(context, data->database);
+ grn_ctx_fin(context);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchReporter *reporter;
+ gint n = 10;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+
+ g_print("Process %d times in each pattern\n", n);
+
+ bench_init(&argc, &argv);
+ reporter = bench_reporter_new();
+
+ {
+ BenchmarkData data_small_with_mruby;
+ BenchmarkData data_small_without_mruby;
+ BenchmarkData data_medium_with_mruby;
+ BenchmarkData data_medium_without_mruby;
+ BenchmarkData data_large_with_mruby;
+ BenchmarkData data_large_without_mruby;
+ BenchmarkData data_very_large_with_mruby;
+ BenchmarkData data_very_large_without_mruby;
+
+#define REGISTER(data, n_records_, min, max, use_mruby_) \
+ do { \
+ gchar *label; \
+ label = g_strdup_printf("(%6d, %6d] (%7d): %7s mruby", \
+ min, max, n_records_, \
+ use_mruby_ ? "with" : "without"); \
+ data.use_mruby = use_mruby_; \
+ data.n_records = n_records_; \
+ data.command = \
+ "select Entries --cache no " \
+ "--filter 'rank > " #min " && rank <= " #max "'"; \
+ bench_startup(&data); \
+ bench_reporter_register(reporter, label, \
+ n, \
+ NULL, \
+ bench, \
+ NULL, \
+ &data); \
+ g_free(label); \
+ } while(FALSE)
+
+ REGISTER(data_small_with_mruby,
+ 1000,
+ 500, 600,
+ GRN_TRUE);
+ REGISTER(data_small_without_mruby,
+ 1000,
+ 500, 600,
+ GRN_FALSE);
+ REGISTER(data_medium_with_mruby,
+ 10000,
+ 5000, 5100,
+ GRN_TRUE);
+ REGISTER(data_medium_without_mruby,
+ 10000,
+ 5000, 5100,
+ GRN_FALSE);
+ REGISTER(data_large_with_mruby,
+ 100000,
+ 50000, 50100,
+ GRN_TRUE);
+ REGISTER(data_large_without_mruby,
+ 100000,
+ 50000, 50100,
+ GRN_FALSE);
+ REGISTER(data_very_large_with_mruby,
+ 1000000,
+ 500000, 500100,
+ GRN_TRUE);
+ REGISTER(data_very_large_without_mruby,
+ 1000000,
+ 500000, 500100,
+ GRN_FALSE);
+
+#undef REGISTER
+
+ bench_reporter_run(reporter);
+
+ bench_shutdown(&data_small_with_mruby);
+ bench_shutdown(&data_small_without_mruby);
+ bench_shutdown(&data_medium_with_mruby);
+ bench_shutdown(&data_medium_without_mruby);
+ bench_shutdown(&data_large_with_mruby);
+ bench_shutdown(&data_large_without_mruby);
+ bench_shutdown(&data_very_large_with_mruby);
+ bench_shutdown(&data_very_large_without_mruby);
+ }
+ g_object_unref(reporter);
+
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-result-set.c b/storage/mroonga/vendor/groonga/benchmark/bench-result-set.c
new file mode 100644
index 00000000..bba5baea
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-result-set.c
@@ -0,0 +1,151 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2015-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+typedef struct _BenchmarkData
+{
+ gchar *base_dir;
+ grn_ctx *context;
+ grn_obj *source_table;
+ grn_obj *result_set;
+} BenchmarkData;
+
+static void
+bench_n(BenchmarkData *data, gint64 n)
+{
+ gint64 i;
+ grn_ctx *ctx;
+ grn_hash *result_set;
+
+ ctx = data->context;
+ result_set = (grn_hash *)data->result_set;
+ for (i = 0; i < n; i++) {
+ grn_id id = i;
+ grn_hash_add(ctx, result_set, &id, sizeof(grn_id), NULL, NULL);
+ }
+}
+
+static void
+bench_1000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 1000);
+}
+
+static void
+bench_10000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 10000);
+}
+
+static void
+bench_100000(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ bench_n(data, 100000);
+}
+
+static void
+bench_setup(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ data->result_set = grn_table_create(data->context,
+ NULL, 0, NULL,
+ GRN_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
+ data->source_table,
+ NULL);
+
+}
+
+static void
+bench_teardown(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_obj_close(data->context, data->result_set);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchmarkData data;
+ BenchReporter *reporter;
+ gchar *base_dir;
+ grn_ctx ctx;
+ gint n = 100;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ data.context = &ctx;
+
+ base_dir = g_build_filename(g_get_tmp_dir(), "groonga-bench", NULL);
+ bench_utils_remove_path_recursive_force(base_dir);
+ g_mkdir_with_parents(base_dir, 0755);
+
+ {
+ gchar *database_path;
+ const gchar *source_table_name = "Sources";
+
+ grn_ctx_init(&ctx, 0);
+ database_path = g_build_filename(base_dir, "db", NULL);
+ grn_db_create(&ctx, database_path, NULL);
+ g_free(database_path);
+
+ data.source_table = grn_table_create(&ctx,
+ source_table_name,
+ strlen(source_table_name),
+ NULL,
+ GRN_TABLE_PAT_KEY | GRN_OBJ_PERSISTENT,
+ grn_ctx_at(&ctx, GRN_DB_SHORT_TEXT),
+ NULL);
+ }
+
+ reporter = bench_reporter_new();
+ bench_reporter_register(reporter, "1000", n,
+ bench_setup, bench_1000, bench_teardown, &data);
+ bench_reporter_register(reporter, "10000", n,
+ bench_setup, bench_10000, bench_teardown, &data);
+ bench_reporter_register(reporter, "100000", n,
+ bench_setup, bench_100000, bench_teardown, &data);
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ grn_ctx_fin(&ctx);
+
+ bench_utils_remove_path_recursive_force(data.base_dir);
+
+ bench_quit();
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c b/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c
new file mode 100644
index 00000000..025b0750
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/bench-table-factory.c
@@ -0,0 +1,277 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2008-2016 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <groonga.h>
+
+#include "lib/benchmark.h"
+
+#define DEFAULT_FLAGS (GRN_OBJ_PERSISTENT | GRN_OBJ_TABLE_PAT_KEY)
+#define DEFAULT_VALUE_SIZE (1024)
+#define VALUE_TYPE_NAME "<value_type>"
+
+typedef struct _BenchmarkData
+{
+ gchar *base_dir;
+
+ grn_ctx *context;
+ const char *name;
+ unsigned name_size;
+ char *path;
+ grn_obj_flags flags;
+ grn_obj *key_type;
+ unsigned value_size;
+ grn_encoding encoding;
+} BenchmarkData;
+
+static void
+bench_normal(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ grn_obj *table;
+ grn_obj *value_type = grn_ctx_get(data->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME));
+ if (!value_type) {
+ value_type = grn_type_create(data->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME),
+ 0, data->value_size);
+ }
+ table = grn_table_create(data->context,
+ data->name, data->name_size,
+ data->path, data->flags,
+ data->key_type, value_type);
+ grn_obj_close(data->context, table);
+}
+
+static void
+bench_normal_temporary(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ grn_obj *table;
+ grn_obj *value_type = grn_ctx_get(data->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME));
+ if (!value_type) {
+ value_type = grn_type_create(data->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME),
+ 0, data->value_size);
+ }
+ GRN_CTX_SET_ENCODING(data->context, data->encoding);
+ table = grn_table_create(data->context,
+ data->name, data->name_size,
+ NULL, data->flags & ~GRN_OBJ_PERSISTENT,
+ data->key_type, value_type);
+ grn_obj_close(data->context, table);
+}
+
+typedef struct _grn_table_factory
+{
+ grn_ctx *context;
+ char *name;
+ unsigned name_size;
+ char *path;
+ grn_obj_flags flags;
+ grn_obj *key_type;
+ unsigned value_size;
+ grn_encoding encoding;
+} grn_table_factory;
+
+static grn_table_factory *
+grn_table_factory_create(void)
+{
+ grn_table_factory *factory;
+
+ factory = g_new0(grn_table_factory, 1);
+
+ factory->context = NULL;
+ factory->name = NULL;
+ factory->name_size = 0;
+ factory->path = NULL;
+ factory->flags = DEFAULT_FLAGS;
+ factory->key_type = NULL;
+ factory->value_size = DEFAULT_VALUE_SIZE;
+ factory->encoding = GRN_ENC_DEFAULT;
+
+ return factory;
+}
+
+static void
+grn_table_factory_set_context(grn_table_factory *factory, grn_ctx *context)
+{
+ factory->context = context;
+}
+
+static void
+grn_table_factory_set_name(grn_table_factory *factory, const char *name)
+{
+ factory->name = g_strdup(name);
+ factory->name_size = strlen(name);
+}
+
+static void
+grn_table_factory_set_path(grn_table_factory *factory, const char *path)
+{
+ factory->path = g_strdup(path);
+ if (path)
+ factory->flags |= GRN_OBJ_PERSISTENT;
+ else
+ factory->flags &= ~GRN_OBJ_PERSISTENT;
+}
+
+static void
+grn_table_factory_set_key_type(grn_table_factory *factory, grn_obj *key_type)
+{
+ factory->key_type = key_type;
+}
+
+static grn_obj *
+grn_table_factory_make(grn_table_factory *factory)
+{
+ grn_obj *value_type = grn_ctx_get(factory->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME));
+ if (!value_type) {
+ value_type = grn_type_create(factory->context, VALUE_TYPE_NAME, strlen(VALUE_TYPE_NAME),
+ 0, factory->value_size);
+ }
+ GRN_CTX_SET_ENCODING(factory->context, factory->encoding);
+ return grn_table_create(factory->context,
+ factory->name, factory->name_size,
+ factory->path, factory->flags,
+ factory->key_type, value_type);
+}
+
+static void
+grn_table_factory_close(grn_table_factory *factory)
+{
+ g_free(factory->name);
+ g_free(factory->path);
+ g_free(factory);
+}
+
+static void
+bench_factory(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ grn_table_factory *factory;
+ grn_obj *table;
+
+ factory = grn_table_factory_create();
+ grn_table_factory_set_context(factory, data->context);
+ grn_table_factory_set_name(factory, data->name);
+ grn_table_factory_set_path(factory, data->path);
+ grn_table_factory_set_key_type(factory, data->key_type);
+
+ table = grn_table_factory_make(factory);
+ grn_obj_close(data->context, table);
+
+ grn_table_factory_close(factory);
+}
+
+static void
+bench_factory_temporary(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ grn_table_factory *factory;
+ grn_obj *table;
+
+ factory = grn_table_factory_create();
+ grn_table_factory_set_context(factory, data->context);
+ grn_table_factory_set_name(factory, data->name);
+ grn_table_factory_set_key_type(factory, data->key_type);
+
+ table = grn_table_factory_make(factory);
+ grn_obj_close(data->context, table);
+
+ grn_table_factory_close(factory);
+}
+
+static void
+bench_setup(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+ const gchar *type_name;
+
+ bench_utils_remove_path_recursive_force(data->base_dir);
+ g_mkdir_with_parents(data->base_dir, 0755);
+
+ grn_ctx_init(data->context, GRN_CTX_USE_QL);
+
+ type_name = "name";
+ data->key_type = grn_type_create(data->context,
+ type_name, strlen(type_name),
+ GRN_OBJ_KEY_UINT, sizeof(grn_id));
+
+}
+
+static void
+bench_teardown(gpointer user_data)
+{
+ BenchmarkData *data = user_data;
+
+ grn_obj_close(data->context, data->key_type);
+ grn_ctx_fin(data->context);
+ bench_utils_remove_path_recursive_force(data->base_dir);
+}
+
+int
+main(int argc, gchar **argv)
+{
+ grn_rc rc;
+ BenchmarkData data;
+ BenchReporter *reporter;
+ gint n = 100;
+
+ rc = grn_init();
+ if (rc != GRN_SUCCESS) {
+ g_print("failed to initialize Groonga: <%d>: %s\n",
+ rc, grn_get_global_error_message());
+ return EXIT_FAILURE;
+ }
+ bench_init(&argc, &argv);
+
+ data.context = g_new(grn_ctx, 1);
+ data.base_dir = g_build_filename(g_get_tmp_dir(), "groonga-bench", NULL);
+ data.name = "table";
+ data.name_size = strlen(data.name);
+ data.path = g_build_filename(data.base_dir, "table", NULL);
+ data.flags = DEFAULT_FLAGS;
+ data.key_type = NULL;
+ data.value_size = DEFAULT_VALUE_SIZE;
+ data.encoding = GRN_ENC_DEFAULT;
+
+ reporter = bench_reporter_new();
+ bench_reporter_register(reporter, "normal (persistent)", n,
+ bench_setup, bench_normal, bench_teardown, &data);
+ bench_reporter_register(reporter, "factory (persistent)", n,
+ bench_setup, bench_factory, bench_teardown, &data);
+ bench_reporter_register(reporter, "normal (temporary)", n,
+ bench_setup, bench_normal_temporary, bench_teardown,
+ &data);
+ bench_reporter_register(reporter, "factory (temporary)", n,
+ bench_setup, bench_factory_temporary, bench_teardown,
+ &data);
+ bench_reporter_run(reporter);
+ g_object_unref(reporter);
+
+ bench_utils_remove_path_recursive_force(data.base_dir);
+
+ g_free(data.path);
+ g_free(data.base_dir);
+ g_free(data.context);
+
+ bench_quit();
+ grn_fin();
+
+ return EXIT_SUCCESS;
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/fixtures/Makefile.am
new file mode 100644
index 00000000..3b7136f7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS = \
+ geo-select
diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/13_2010.CSV.xz b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/13_2010.CSV.xz
new file mode 100644
index 00000000..3cef5268
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/13_2010.CSV.xz
Binary files differ
diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/Makefile.am
new file mode 100644
index 00000000..3aa25594
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/Makefile.am
@@ -0,0 +1,4 @@
+EXTRA_DIST = \
+ README.txt \
+ 13_2010.CSV.xz \
+ format_2010.html
diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/README.txt b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/README.txt
new file mode 100644
index 00000000..c4a0620a
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/README.txt
@@ -0,0 +1,6 @@
+位置情報検索ベンチマーク用テストデータについて
+--------------------------------------------
+
+13_2010.CSV.xzは国土交通相の `位置参照情報ダウンロードサービス <http://nlftp.mlit.go.jp/isj/>`_ からダウンロードした2010年版の東京都の「大字・町丁目位置参照情報 国土交通省」です。xz圧縮しているだけでデータの編集・加工はしていません。CSVのフォーマットについてはformat_2010.htmlを参照してください。こちらもダウンロードサービスに含まれているものを編集・加工していません。
+
+`位置参照情報ダウンロードサービス利用約款 <http://nlftp.mlit.go.jp/isj/agreement.html>`_ に従い、上記のように出典を明記して利用しています。
diff --git a/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/format_2010.html b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/format_2010.html
new file mode 100644
index 00000000..5c2396c4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/fixtures/geo-select/format_2010.html
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+<title>X惌xʒuQƏ (2010)</title>
+<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
+</head>
+
+ <body>
+ <h3 align="center">X惌xʒuQƏ (2010N) f[^`</h3>
+ <table width="90%" align="center">
+ <tr>
+ <td>
+ t@C`CSV(Camma Separated Values)łB<br/>
+ R[h́AShift-JISłB<br/>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table width="100%" align="center" border="1">
+ <tr>
+ <th></th>
+ <th>l</th>
+ <th></th>
+ </tr>
+ <tr>
+ <td>s{</td>
+ <td><br/></td>
+ <td>"s"</td>
+ </tr>
+ <tr>
+ <td>s撬</td>
+ <td>S͌SAߎwss̋於܂ށB</td>
+ <td>"c"</td>
+ </tr>
+ <tr>
+ <td>厚E</td>
+ <td>ڂ̐͊</td>
+ <td>"֓񒚖"</td>
+ </tr>
+ <tr>
+ <td>X敄En</td>
+ <td>ƂĔpiꕔj</td>
+ <td>"1"</td>
+ </tr>
+ <tr>
+ <td>Wnԍ</td>
+ <td>ʒpWn̍Wnԍi1`19Fpj</td>
+ <td>9</td>
+ </tr>
+ <tr>
+ <td>wW</td>
+ <td>
+ ʒpWn̍Wn_̂<br/>
+ iPʁF[gAkvXlA_ȉ1ʂ܂Łj
+ </td>
+ <td>-35925.9</td>
+ </tr>
+ <tr>
+ <td>xW</td>
+ <td>
+ ʒpWn̍Wn_̂<br/>
+ iPʁF[gAvXlA_ȉ1ʂ܂Łj
+ </td>
+ <td>-7446.2</td>
+ </tr>
+ <tr>
+ <td>ܓx</td>
+ <td>\ioܓxiPʁFxA_ȉ6ʂ܂Łj</td>
+ <td>35.676155</td>
+ </tr>
+ <tr>
+ <td>ox</td>
+ <td>\ioܓxiPʁFxA_ȉ6ʂ܂Łj</td>
+ <td>139.751075</td>
+ </tr>
+ <tr>
+ <td>Z\tO</td>
+ <td>1FZ\{A0FZ\{</td>
+ <td>1</td>
+ </tr>
+ <tr>
+ <td>\tO</td>
+ <td>
+ 1‚̊X敄̑\_ɑΉtꍇȂǂɁÂ1‚ɕ֋XIɑ\tO𗧂ĂĂ܂B<br/>
+ 1F\A0F\Ȃ
+ <td>1</td>
+ </tr>
+ <tr>
+ <td>XVOtO</td>
+ <td>2007Nx2008Nxf[^Ɋ܂܂tO𗧂ĂĂ܂B<br/>
+ 1FVK쐬A2F̕ύXA3F폜A0FύXȂ</td>
+ <td>0</td>
+ </tr>
+ <tr>
+ <td>XV㗚tO</td>
+ <td>2009Nxȍ~̃f[^Ɋ܂܂tO𗧂ĂĂ܂B<br/>
+ 1FVK쐬A2F̕ύXA3F폜A0FύXȂ</td>
+ <td>0</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td align="right">
+ 23N0418쐬
+ </td>
+ </tr>
+ </table>
+</body>
+
+</html>
diff --git a/storage/mroonga/vendor/groonga/benchmark/geo-distance-summary.rb b/storage/mroonga/vendor/groonga/benchmark/geo-distance-summary.rb
new file mode 100755
index 00000000..6559cb60
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/geo-distance-summary.rb
@@ -0,0 +1,140 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+require 'fileutils'
+require 'optparse'
+
+class BenchmarkSummary
+ attr_accessor :options
+
+ def initialize(options)
+ @options = options
+ @options[:count] ||= 10
+ end
+
+ def calc_total(data)
+ total = {}
+ @options[:count].times do |i|
+ data[i + 1].each do |key, value|
+ if total[key]
+ total[key] = total[key] + value
+ else
+ total[key] = value
+ end
+ end
+ end
+ total
+ end
+
+ def print_average(data)
+ total = calc_total(data)
+ text = "|項目|"
+ @options[:count].times do |i|
+ text << "#{i + 1}|"
+ text << "平均|\n" if i == @options[:count] - 1
+ end
+ total.each do |key, value|
+ line = [key]
+ @options[:count].times do |i|
+ data[i + 1].each do |data_key, data_value|
+ if key == data_key
+ line << data_value
+ end
+ end
+ end
+ line << [value / @options[:count].to_f]
+ text << sprintf("|%s|\n", line.join("|"))
+ end
+ puts text
+ end
+
+ def print_performance(before, after)
+ before_total = calc_total(before)
+ after_total = calc_total(after)
+ ratio = {}
+ before_total.each do |key, value|
+ ratio[key] = after_total[key] / value
+ end
+ text = "|項目|変更前|変更後|比率|備考|\n"
+ ratio.each do |key, value|
+ text << sprintf("|%s|%f|%f|%f||\n",
+ key,
+ before_total[key] / @options[:count].to_f,
+ after_total[key] / @options[:count].to_f,
+ ratio[key])
+ end
+ puts text
+ end
+
+ def parse_log(logs)
+ parse_result = {}
+ logs.each do |index, log|
+ File.open(log, "r") do |file|
+ data = file.read
+ entry = {}
+ data.split("\n").each do |line|
+ if line =~ /\s*(.+?):\s+\((.+)\)/
+ entry[$1] = $2.to_f
+ end
+ end
+ parse_result[index] = entry
+ end
+ end
+ parse_result
+ end
+end
+
+=begin
+
+Usage: geo-distance-summary.rb \
+-b run-bench-geo-distance-orig-N1000 \
+-a run-bench-geo-distance-work-N1000
+
+NOTE: expected that there are run-bench-geo-distance-orig-N1000-1.log \
+... \
+run-bench-geo-distance-orig-N1000-[N].log.
+
+=end
+
+if __FILE__ == $0
+
+ options = {}
+ parser = OptionParser.new
+ parser.on("-b", "--before PREFIX",
+ "log file name must be PREFIX-[N].log") do |prefix|
+ options[:before] = prefix
+ end
+ parser.on("-a", "--after PREFIX",
+ "log file name must be PREFIX-[N].log") do |prefix|
+ options[:after] = prefix
+ end
+ parser.on("-n", "data count") do |count|
+ options[:count] = count
+ end
+
+ parser.parse!(ARGV)
+
+ if not options.has_key?(:before) or not options.has_key?(:after)
+ puts(parser.to_s)
+ exit
+ end
+
+ bench_before_log = {}
+ bench_after_log = {}
+ Dir.glob("#{options[:before]}*.log") do |log|
+ log =~ /(.+)-(\d+)\.log$/
+ bench_before_log[$2.to_i] = log
+ end
+ Dir.glob("#{options[:after]}*.log") do |log|
+ log =~ /(.+)-(\d+)\.log$/
+ bench_after_log[$2.to_i] = log
+ end
+
+ bench = BenchmarkSummary.new(options)
+ bench_before = bench.parse_log(bench_before_log)
+ bench_after = bench.parse_log(bench_after_log)
+
+ bench.print_average(bench_before)
+ bench.print_average(bench_after)
+ bench.print_performance(bench_before, bench_after)
+end
diff --git a/storage/mroonga/vendor/groonga/benchmark/geo-select-generate-grn.rb b/storage/mroonga/vendor/groonga/benchmark/geo-select-generate-grn.rb
new file mode 100755
index 00000000..dc90f7e6
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/geo-select-generate-grn.rb
@@ -0,0 +1,53 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+
+if ARGV.size != 2
+ puts "Usage: #{$0} SOURCE_CSV OUTPUT_GRN"
+ puts " e.g.: #{$0} fixtures/geo-select/13_2010.CSV fixtures/geo-select/load.grn"
+ exit(false)
+end
+
+csv, grn = ARGV
+
+require "fileutils"
+require "csv"
+
+FileUtils.mkdir_p(File.dirname(grn))
+File.open(grn, "w") do |output|
+ output.print(<<-EOH.strip)
+table_create Addresses TABLE_HASH_KEY ShortText
+column_create Addresses location COLUMN_SCALAR WGS84GeoPoint
+
+table_create Locations TABLE_PAT_KEY WGS84GeoPoint
+column_create Locations address COLUMN_INDEX Addresses location
+
+load --table Addresses
+[
+["_key", "location"]
+EOH
+
+ headers = nil
+ csv_foreach_args = [csv]
+ csv_foreach_args << {:encoding => "UTF-8"} if defined?(Encoding)
+ CSV.foreach(*csv_foreach_args) do |row|
+ if headers.nil?
+ headers = row
+ else
+ record = {}
+ headers.each_with_index do |header, i|
+ record[header] = row[i]
+ end
+ central_value_p = record["代表フラグ"] == "1"
+ next unless central_value_p
+ name =
+ record["都道府県名"] + record["市区町村名"] +
+ record["大字・町丁目"] + record["街区符号・地番"]
+ location = "%sx%s" % [record["緯度"], record["経度"]]
+ output.print(",\n[\"#{name}\", \"#{location}\"]")
+ end
+ end
+ output.print(<<-EOF)
+
+]
+EOF
+end
diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am b/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am
new file mode 100644
index 00000000..2031b9aa
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/lib/Makefile.am
@@ -0,0 +1,24 @@
+if WITH_BENCHMARK
+noinst_LTLIBRARIES = \
+ libbenchmark.la
+endif
+
+AM_CPPFLAGS = \
+ -I$(srcdir)
+
+AM_CFLAGS = \
+ $(GLIB_CFLAGS)
+
+CFLAGS += \
+ $(NO_BAD_FUNCTION_CAST_CFLAGS)
+
+LIBS = \
+ $(GLIB_LIBS)
+
+libbenchmark_la_SOURCES = \
+ benchmark.c \
+ benchmark.h \
+ bench-reporter.c \
+ bench-reporter.h \
+ bench-utils.c \
+ bench-utils.h
diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.c b/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.c
new file mode 100644
index 00000000..cb435976
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.c
@@ -0,0 +1,315 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#include <string.h>
+
+#include "bench-reporter.h"
+
+typedef struct _BenchItem BenchItem;
+struct _BenchItem
+{
+ gchar *label;
+ gint n;
+ BenchSetupFunc bench_setup;
+ BenchFunc bench;
+ BenchTeardownFunc bench_teardown;
+ gpointer data;
+};
+
+static BenchItem *
+bench_item_new(const gchar *label, gint n,
+ BenchSetupFunc bench_setup,
+ BenchFunc bench,
+ BenchTeardownFunc bench_teardown,
+ gpointer data)
+{
+ BenchItem *item;
+
+ item = g_slice_new(BenchItem);
+
+ item->label = g_strdup(label);
+ item->n = n;
+ item->bench_setup = bench_setup;
+ item->bench = bench;
+ item->bench_teardown = bench_teardown;
+ item->data = data;
+
+ return item;
+}
+
+static void
+bench_item_free(BenchItem *item)
+{
+ if (item->label)
+ g_free(item->label);
+
+ g_slice_free(BenchItem, item);
+}
+
+#define BENCH_REPORTER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ BENCH_TYPE_REPORTER, \
+ BenchReporterPrivate))
+
+typedef struct _BenchReporterPrivate BenchReporterPrivate;
+struct _BenchReporterPrivate
+{
+ GList *items;
+};
+
+G_DEFINE_TYPE(BenchReporter, bench_reporter, G_TYPE_OBJECT)
+
+static void dispose (GObject *object);
+
+static void
+bench_reporter_class_init(BenchReporterClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = dispose;
+
+ g_type_class_add_private(gobject_class, sizeof(BenchReporterPrivate));
+}
+
+static void
+bench_reporter_init(BenchReporter *reporter)
+{
+ BenchReporterPrivate *priv;
+
+ priv = BENCH_REPORTER_GET_PRIVATE(reporter);
+
+ priv->items = NULL;
+}
+
+static void
+dispose(GObject *object)
+{
+ BenchReporterPrivate *priv;
+
+ priv = BENCH_REPORTER_GET_PRIVATE(object);
+
+ if (priv->items) {
+ g_list_foreach(priv->items, (GFunc)bench_item_free, NULL);
+ g_list_free(priv->items);
+ priv->items = NULL;
+ }
+
+ G_OBJECT_CLASS(bench_reporter_parent_class)->dispose(object);
+}
+
+BenchReporter *
+bench_reporter_new(void)
+{
+ return g_object_new(BENCH_TYPE_REPORTER, NULL);
+}
+
+void
+bench_reporter_register(BenchReporter *reporter,
+ const gchar *label, gint n,
+ BenchSetupFunc bench_setup,
+ BenchFunc bench,
+ BenchTeardownFunc bench_teardown,
+ gpointer data)
+{
+ BenchReporterPrivate *priv;
+
+ priv = BENCH_REPORTER_GET_PRIVATE(reporter);
+
+ priv->items = g_list_append(priv->items, bench_item_new(label, n,
+ bench_setup,
+ bench,
+ bench_teardown,
+ data));
+}
+
+#define INDENT " "
+
+static void
+print_header(BenchReporterPrivate *priv, gint max_label_length)
+{
+ gint n_spaces;
+
+ g_print(INDENT);
+ for (n_spaces = max_label_length + strlen(": ");
+ n_spaces > 0;
+ n_spaces--) {
+ g_print(" ");
+ }
+ g_print("(total) ");
+ g_print("(average) ");
+ g_print("(median)\n");
+}
+
+static void
+print_label(BenchReporterPrivate *priv, BenchItem *item, gint max_label_length)
+{
+ gint n_left_spaces;
+
+ g_print(INDENT);
+ if (item->label) {
+ n_left_spaces = max_label_length - strlen(item->label);
+ } else {
+ n_left_spaces = max_label_length;
+ }
+ for (; n_left_spaces > 0; n_left_spaces--) {
+ g_print(" ");
+ }
+ if (item->label)
+ g_print("%s", item->label);
+ g_print(": ");
+}
+
+static void
+report_elapsed_time(gdouble elapsed_time)
+{
+ gdouble one_second = 1.0;
+ gdouble one_millisecond = one_second / 1000.0;
+ gdouble one_microsecond = one_millisecond / 1000.0;
+
+ if (elapsed_time < one_microsecond) {
+ g_print("(%.8fms)", elapsed_time * 1000.0);
+ } else if (elapsed_time < one_millisecond) {
+ g_print("(%.4fms)", elapsed_time * 1000.0);
+ } else {
+ g_print("(%.4fs) ", elapsed_time);
+ }
+}
+
+static gdouble
+compute_total_elapsed_time(GArray *elapsed_times)
+{
+ guint i;
+ gdouble total = 0.0;
+
+ for (i = 0; i< elapsed_times->len; i++) {
+ gdouble elapsed_time = g_array_index(elapsed_times, gdouble, i);
+ total += elapsed_time;
+ }
+
+ return total;
+}
+
+static void
+report_elapsed_time_total(GArray *elapsed_times)
+{
+ report_elapsed_time(compute_total_elapsed_time(elapsed_times));
+}
+
+static void
+report_elapsed_time_average(GArray *elapsed_times)
+{
+ gdouble total;
+ gdouble average;
+
+ total = compute_total_elapsed_time(elapsed_times);
+ average = total / elapsed_times->len;
+ report_elapsed_time(average);
+}
+
+static gint
+compare_elapsed_time(gconstpointer a, gconstpointer b)
+{
+ const gdouble *elapsed_time1 = a;
+ const gdouble *elapsed_time2 = b;
+
+ if (*elapsed_time1 > *elapsed_time2) {
+ return 1;
+ } else if (*elapsed_time1 < *elapsed_time2) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+static void
+report_elapsed_time_median(GArray *elapsed_times)
+{
+ gdouble median;
+
+ g_array_sort(elapsed_times, compare_elapsed_time);
+ median = g_array_index(elapsed_times, gdouble, elapsed_times->len / 2);
+ report_elapsed_time(median);
+}
+
+static void
+report_elapsed_time_statistics(GArray *elapsed_times)
+{
+ report_elapsed_time_total(elapsed_times);
+ g_print(" ");
+ report_elapsed_time_average(elapsed_times);
+ g_print(" ");
+ report_elapsed_time_median(elapsed_times);
+ g_print("\n");
+}
+
+static void
+run_item(BenchReporterPrivate *priv, BenchItem *item, gint max_label_length)
+{
+ GTimer *timer;
+ GArray *elapsed_times;
+ gint i;
+
+ print_label(priv, item, max_label_length);
+
+ elapsed_times = g_array_new(FALSE, FALSE, sizeof(gdouble));
+
+ timer = g_timer_new();
+ for (i = 0; i < item->n; i++) {
+ gdouble elapsed_time;
+ if (item->bench_setup)
+ item->bench_setup(item->data);
+ g_timer_start(timer);
+ item->bench(item->data);
+ g_timer_stop(timer);
+ elapsed_time = g_timer_elapsed(timer, NULL);
+ g_array_append_val(elapsed_times, elapsed_time);
+ if (item->bench_teardown)
+ item->bench_teardown(item->data);
+ }
+ g_timer_destroy(timer);
+
+ report_elapsed_time_statistics(elapsed_times);
+
+ g_array_free(elapsed_times, TRUE);
+
+}
+
+void
+bench_reporter_run(BenchReporter *reporter)
+{
+ BenchReporterPrivate *priv;
+ GList *node;
+ gint max_label_length = 0;
+
+ priv = BENCH_REPORTER_GET_PRIVATE(reporter);
+ for (node = priv->items; node; node = g_list_next(node)) {
+ BenchItem *item = node->data;
+
+ if (item->label)
+ max_label_length = MAX(max_label_length, strlen(item->label));
+ }
+
+ print_header(priv, max_label_length);
+ for (node = priv->items; node; node = g_list_next(node)) {
+ BenchItem *item = node->data;
+
+ run_item(priv, item, max_label_length);
+ }
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.h b/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.h
new file mode 100644
index 00000000..d2c408c7
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/lib/bench-reporter.h
@@ -0,0 +1,64 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#ifndef __BENCH_REPORTER_H__
+#define __BENCH_REPORTER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define BENCH_TYPE_REPORTER (bench_reporter_get_type())
+#define BENCH_REPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), BENCH_TYPE_REPORTER, BenchReporter))
+#define BENCH_REPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), BENCH_TYPE_REPORTER, BenchReporterClass))
+#define BENCH_IS_REPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), BENCH_TYPE_REPORTER))
+#define BENCH_IS_REPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), BENCH_TYPE_REPORTER))
+#define BENCH_REPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), BENCH_TYPE_REPORTER, BenchReporterClass))
+
+typedef struct _BenchReporter BenchReporter;
+typedef struct _BenchReporterClass BenchReporterClass;
+
+typedef void (*BenchSetupFunc) (gpointer user_data);
+typedef void (*BenchFunc) (gpointer user_data);
+typedef void (*BenchTeardownFunc) (gpointer user_data);
+
+struct _BenchReporter
+{
+ GObject object;
+};
+
+struct _BenchReporterClass
+{
+ GObjectClass parent_class;
+};
+
+GType bench_reporter_get_type (void) G_GNUC_CONST;
+
+BenchReporter *bench_reporter_new (void);
+void bench_reporter_register (BenchReporter *reporter,
+ const gchar *label,
+ gint n,
+ BenchSetupFunc bench_setup,
+ BenchFunc bench,
+ BenchTeardownFunc bench_teardown,
+ gpointer data);
+void bench_reporter_run (BenchReporter *reporter);
+
+#endif /* __BENCH_REPORTER_H__ */
+
+
diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.c b/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.c
new file mode 100644
index 00000000..ef731b51
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.c
@@ -0,0 +1,83 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#include <errno.h>
+#include <glib/gstdio.h>
+
+#include "bench-utils.h"
+
+gboolean
+bench_utils_remove_path(const gchar *path, GError **error)
+{
+ if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
+ g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_NOENT,
+ "path doesn't exist: %s", path);
+ return FALSE;
+ }
+
+ if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
+ if (g_rmdir(path) == -1) {
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno),
+ "can't remove directory: %s", path);
+ return FALSE;
+ }
+ } else {
+ if (g_unlink(path) == -1) {
+ g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno),
+ "can't remove path: %s", path);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean
+bench_utils_remove_path_recursive(const gchar *path, GError **error)
+{
+ if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
+ GDir *dir;
+ const gchar *name;
+
+ dir = g_dir_open(path, 0, error);
+ if (!dir)
+ return FALSE;
+
+ while ((name = g_dir_read_name(dir))) {
+ const gchar *full_path;
+
+ full_path = g_build_filename(path, name, NULL);
+ if (!bench_utils_remove_path_recursive(full_path, error))
+ return FALSE;
+ }
+
+ g_dir_close(dir);
+
+ return bench_utils_remove_path(path, error);
+ } else {
+ return bench_utils_remove_path(path, error);
+ }
+
+ return TRUE;
+}
+
+void
+bench_utils_remove_path_recursive_force(const gchar *path)
+{
+ bench_utils_remove_path_recursive(path, NULL);
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.h b/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.h
new file mode 100644
index 00000000..b48e6f34
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/lib/bench-utils.h
@@ -0,0 +1,34 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#ifndef __BENCH_UTILS_H__
+#define __BENCH_UTILS_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gboolean bench_utils_remove_path (const gchar *path,
+ GError **error);
+gboolean bench_utils_remove_path_recursive (const gchar *path,
+ GError **error);
+void bench_utils_remove_path_recursive_force (const gchar *path);
+
+G_END_DECLS
+
+#endif /* __BENCH_UTILS_H__ */
diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.c b/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.c
new file mode 100644
index 00000000..679889a4
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.c
@@ -0,0 +1,35 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2008-2013 Kouhei Sutou <kou@clear-code.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#include "benchmark.h"
+
+void
+bench_init(gint *argc, gchar ***argv)
+{
+#if !GLIB_CHECK_VERSION(2, 36, 0)
+ if (!g_thread_supported())
+ g_thread_init(NULL);
+
+ g_type_init();
+#endif
+}
+
+void
+bench_quit(void)
+{
+}
diff --git a/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.h b/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.h
new file mode 100644
index 00000000..7d34b8f2
--- /dev/null
+++ b/storage/mroonga/vendor/groonga/benchmark/lib/benchmark.h
@@ -0,0 +1,32 @@
+/* -*- c-basic-offset: 2; coding: utf-8 -*- */
+/*
+ Copyright (C) 2008 Kouhei Sutou <kou@cozmixng.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
+*/
+
+#ifndef __BENCHMARK_H__
+#define __BENCHMARK_H__
+
+#include "bench-reporter.h"
+#include "bench-utils.h"
+
+G_BEGIN_DECLS
+
+void bench_init(gint *argc, gchar ***argv);
+void bench_quit(void);
+
+G_END_DECLS
+
+#endif