rroonga 1.0.1-x86-mingw32 → 1.1.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (387) hide show
  1. data/NEWS.ja.rdoc +146 -0
  2. data/NEWS.rdoc +146 -0
  3. data/README.ja.rdoc +7 -5
  4. data/README.rdoc +6 -5
  5. data/Rakefile +170 -18
  6. data/benchmark/create-wikipedia-database.rb +212 -0
  7. data/benchmark/read-write-many-small-items.rb +0 -0
  8. data/benchmark/repeat-load.rb +213 -0
  9. data/benchmark/select.rb +1052 -0
  10. data/benchmark/write-many-small-items.rb +0 -0
  11. data/example/bookmark.rb +94 -91
  12. data/example/index-html.rb +0 -0
  13. data/ext/groonga/extconf.rb +6 -6
  14. data/ext/groonga/rb-grn-accessor.c +1 -1
  15. data/ext/groonga/rb-grn-array.c +1 -1
  16. data/ext/groonga/rb-grn-column.c +201 -10
  17. data/ext/groonga/rb-grn-context.c +119 -20
  18. data/ext/groonga/rb-grn-database.c +27 -4
  19. data/ext/groonga/rb-grn-exception.c +15 -0
  20. data/ext/groonga/rb-grn-expression.c +14 -10
  21. data/ext/groonga/rb-grn-hash.c +4 -4
  22. data/ext/groonga/rb-grn-index-column.c +10 -6
  23. data/ext/groonga/rb-grn-logger.c +2 -2
  24. data/ext/groonga/rb-grn-object.c +33 -29
  25. data/ext/groonga/{rb-grn-operation.c → rb-grn-operator.c} +89 -87
  26. data/ext/groonga/rb-grn-patricia-trie.c +12 -12
  27. data/ext/groonga/rb-grn-plugin.c +134 -0
  28. data/ext/groonga/rb-grn-procedure.c +1 -1
  29. data/ext/groonga/rb-grn-query.c +7 -7
  30. data/ext/groonga/rb-grn-snippet.c +4 -3
  31. data/ext/groonga/rb-grn-table-cursor.c +1 -1
  32. data/ext/groonga/rb-grn-table-key-support.c +27 -24
  33. data/ext/groonga/rb-grn-table.c +119 -58
  34. data/ext/groonga/rb-grn-type.c +1 -1
  35. data/ext/groonga/rb-grn-utils.c +20 -19
  36. data/ext/groonga/rb-grn-variable.c +1 -1
  37. data/ext/groonga/rb-grn-view-accessor.c +1 -1
  38. data/ext/groonga/rb-grn-view.c +1 -1
  39. data/ext/groonga/rb-grn.h +26 -20
  40. data/ext/groonga/rb-groonga.c +6 -4
  41. data/extconf.rb +10 -4
  42. data/html/developer.html +8 -2
  43. data/html/favicon.ico +0 -0
  44. data/html/favicon.svg +591 -0
  45. data/html/index.html +78 -12
  46. data/html/logo.svg +612 -0
  47. data/html/ranguba.css +92 -7
  48. data/html/readme.svg +256 -0
  49. data/lib/groonga.so +0 -0
  50. data/lib/groonga/context.rb +52 -1
  51. data/lib/groonga/expression-builder.rb +42 -6
  52. data/lib/groonga/record.rb +84 -15
  53. data/lib/groonga/schema.rb +524 -122
  54. data/pkg/rroonga-1.1.0-x86-mingw32/NEWS.ja.rdoc +326 -0
  55. data/pkg/rroonga-1.1.0-x86-mingw32/NEWS.rdoc +328 -0
  56. data/pkg/rroonga-1.1.0-x86-mingw32/README.ja.rdoc +68 -0
  57. data/pkg/rroonga-1.1.0-x86-mingw32/README.rdoc +68 -0
  58. data/pkg/rroonga-1.1.0-x86-mingw32/text/expression.rdoc +285 -0
  59. data/{text/TUTORIAL.ja.rdoc → pkg/rroonga-1.1.0-x86-mingw32/text/tutorial.ja.rdoc} +165 -126
  60. data/pkg/rroonga-1.1.0/NEWS.ja.rdoc +326 -0
  61. data/pkg/rroonga-1.1.0/NEWS.rdoc +328 -0
  62. data/pkg/rroonga-1.1.0/README.ja.rdoc +68 -0
  63. data/pkg/rroonga-1.1.0/README.rdoc +68 -0
  64. data/pkg/rroonga-1.1.0/text/expression.rdoc +285 -0
  65. data/pkg/rroonga-1.1.0/text/tutorial.ja.rdoc +433 -0
  66. data/rroonga-build.rb +3 -3
  67. data/test/run-test.rb +1 -1
  68. data/test/test-array.rb +4 -0
  69. data/test/test-column.rb +31 -1
  70. data/test/test-context-select.rb +45 -14
  71. data/test/test-context.rb +44 -0
  72. data/test/test-database.rb +21 -1
  73. data/test/test-expression-builder.rb +46 -5
  74. data/test/test-fix-size-column.rb +12 -0
  75. data/test/test-hash.rb +10 -4
  76. data/test/test-index-column.rb +33 -0
  77. data/test/test-patricia-trie.rb +6 -0
  78. data/test/test-plugin.rb +29 -0
  79. data/test/test-record.rb +84 -1
  80. data/test/test-remote.rb +3 -2
  81. data/test/test-schema-create-table.rb +32 -2
  82. data/test/test-schema-type.rb +167 -0
  83. data/test/test-schema.rb +159 -12
  84. data/test/test-table-select-weight.rb +20 -1
  85. data/test/test-table-select.rb +12 -0
  86. data/test/test-table.rb +65 -0
  87. data/test/test-variable-size-column.rb +12 -0
  88. data/text/tutorial.ja.rdoc +433 -0
  89. data/vendor/local/bin/grntest.exe +0 -0
  90. data/vendor/local/bin/groonga.exe +0 -0
  91. data/vendor/local/bin/libgroonga-0.dll +0 -0
  92. data/vendor/local/etc/groonga/init.d/redhat/groonga +1 -9
  93. data/vendor/local/include/groonga/groonga.h +156 -6
  94. data/vendor/local/include/groonga/groonga/plugin.h +44 -0
  95. data/vendor/local/lib/groonga/plugins/suggest/suggest.a +0 -0
  96. data/vendor/local/lib/groonga/plugins/suggest/suggest.dll +0 -0
  97. data/vendor/local/lib/groonga/plugins/suggest/suggest.dll.a +0 -0
  98. data/vendor/local/lib/groonga/{modules → plugins}/suggest/suggest.la +2 -2
  99. data/vendor/local/lib/libgroonga.a +0 -0
  100. data/vendor/local/lib/libgroonga.dll.a +0 -0
  101. data/vendor/local/lib/libgroonga.la +1 -1
  102. data/vendor/local/lib/pkgconfig/groonga.pc +3 -2
  103. data/vendor/local/share/groonga/examples/dictionary/edict/edict_import.sh +14 -3
  104. data/vendor/local/share/groonga/examples/dictionary/eijiro/eijiro_import.sh +3 -1
  105. data/vendor/local/share/groonga/examples/dictionary/gene95/gene_import.sh +19 -3
  106. data/vendor/local/share/groonga/munin/plugins/groonga_cpu_load +0 -0
  107. data/vendor/local/share/groonga/munin/plugins/groonga_cpu_time +0 -0
  108. data/vendor/local/share/groonga/munin/plugins/groonga_disk +0 -0
  109. data/vendor/local/share/groonga/munin/plugins/groonga_memory +0 -0
  110. data/vendor/local/share/groonga/munin/plugins/groonga_n_records +0 -0
  111. data/vendor/local/share/groonga/munin/plugins/groonga_query_performance +0 -0
  112. data/vendor/local/share/groonga/munin/plugins/groonga_status +0 -0
  113. metadata +91 -341
  114. data/html/favicon.xcf +0 -0
  115. data/html/logo.xcf +0 -0
  116. data/lib/1.8/groonga.so +0 -0
  117. data/lib/1.9/groonga.so +0 -0
  118. data/license/GPL +0 -340
  119. data/license/RUBY +0 -59
  120. data/vendor/local/lib/groonga/modules/suggest/suggest.a +0 -0
  121. data/vendor/local/lib/groonga/modules/suggest/suggest.dll +0 -0
  122. data/vendor/local/lib/groonga/modules/suggest/suggest.dll.a +0 -0
  123. data/vendor/local/share/groonga/doc/ja/html/.buildinfo +0 -4
  124. data/vendor/local/share/groonga/doc/ja/html/_sources/characteristic.txt +0 -56
  125. data/vendor/local/share/groonga/doc/ja/html/_sources/commands.txt +0 -10
  126. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/cache_limit.txt +0 -52
  127. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/check.txt +0 -164
  128. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/clearlock.txt +0 -61
  129. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/column_create.txt +0 -93
  130. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/column_list.txt +0 -97
  131. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/column_remove.txt +0 -58
  132. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/define_selector.txt +0 -114
  133. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/defrag.txt +0 -57
  134. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/delete.txt +0 -68
  135. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/dump.txt +0 -62
  136. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/load.txt +0 -98
  137. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/log_level.txt +0 -65
  138. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/log_put.txt +0 -69
  139. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/log_reopen.txt +0 -66
  140. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/quit.txt +0 -38
  141. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/select.txt +0 -247
  142. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/shutdown.txt +0 -38
  143. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/status.txt +0 -59
  144. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/suggest.txt +0 -79
  145. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/table_create.txt +0 -111
  146. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/table_list.txt +0 -87
  147. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/table_remove.txt +0 -50
  148. data/vendor/local/share/groonga/doc/ja/html/_sources/commands/view_add.txt +0 -53
  149. data/vendor/local/share/groonga/doc/ja/html/_sources/commands_not_implemented/add.txt +0 -102
  150. data/vendor/local/share/groonga/doc/ja/html/_sources/commands_not_implemented/get.txt +0 -78
  151. data/vendor/local/share/groonga/doc/ja/html/_sources/commands_not_implemented/set.txt +0 -103
  152. data/vendor/local/share/groonga/doc/ja/html/_sources/developer.txt +0 -10
  153. data/vendor/local/share/groonga/doc/ja/html/_sources/developer/com.txt +0 -18
  154. data/vendor/local/share/groonga/doc/ja/html/_sources/developer/document.txt +0 -38
  155. data/vendor/local/share/groonga/doc/ja/html/_sources/developer/query.txt +0 -212
  156. data/vendor/local/share/groonga/doc/ja/html/_sources/developer/test.txt +0 -114
  157. data/vendor/local/share/groonga/doc/ja/html/_sources/execfile.txt +0 -226
  158. data/vendor/local/share/groonga/doc/ja/html/_sources/expr.txt +0 -43
  159. data/vendor/local/share/groonga/doc/ja/html/_sources/functions.txt +0 -10
  160. data/vendor/local/share/groonga/doc/ja/html/_sources/functions/edit_distance.txt +0 -48
  161. data/vendor/local/share/groonga/doc/ja/html/_sources/functions/geo_distance.txt +0 -51
  162. data/vendor/local/share/groonga/doc/ja/html/_sources/functions/geo_in_circle.txt +0 -54
  163. data/vendor/local/share/groonga/doc/ja/html/_sources/functions/geo_in_rectangle.txt +0 -55
  164. data/vendor/local/share/groonga/doc/ja/html/_sources/functions/now.txt +0 -34
  165. data/vendor/local/share/groonga/doc/ja/html/_sources/functions/rand.txt +0 -41
  166. data/vendor/local/share/groonga/doc/ja/html/_sources/grnslap.txt +0 -64
  167. data/vendor/local/share/groonga/doc/ja/html/_sources/grntest.txt +0 -259
  168. data/vendor/local/share/groonga/doc/ja/html/_sources/http.txt +0 -52
  169. data/vendor/local/share/groonga/doc/ja/html/_sources/index.txt +0 -21
  170. data/vendor/local/share/groonga/doc/ja/html/_sources/install.txt +0 -114
  171. data/vendor/local/share/groonga/doc/ja/html/_sources/news.txt +0 -199
  172. data/vendor/local/share/groonga/doc/ja/html/_sources/process.txt +0 -12
  173. data/vendor/local/share/groonga/doc/ja/html/_sources/pseudo_column.txt +0 -38
  174. data/vendor/local/share/groonga/doc/ja/html/_sources/reference.txt +0 -14
  175. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial.txt +0 -10
  176. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial01.txt +0 -293
  177. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial02.txt +0 -100
  178. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial03.txt +0 -72
  179. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial04.txt +0 -111
  180. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial05.txt +0 -65
  181. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial06.txt +0 -91
  182. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial07.txt +0 -92
  183. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial08.txt +0 -53
  184. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial09.txt +0 -9
  185. data/vendor/local/share/groonga/doc/ja/html/_sources/tutorial/tutorial10.txt +0 -486
  186. data/vendor/local/share/groonga/doc/ja/html/_sources/type.txt +0 -118
  187. data/vendor/local/share/groonga/doc/ja/html/_static/basic.css +0 -509
  188. data/vendor/local/share/groonga/doc/ja/html/_static/default.css +0 -277
  189. data/vendor/local/share/groonga/doc/ja/html/_static/doctools.js +0 -247
  190. data/vendor/local/share/groonga/doc/ja/html/_static/file.png +0 -0
  191. data/vendor/local/share/groonga/doc/ja/html/_static/jquery.js +0 -6240
  192. data/vendor/local/share/groonga/doc/ja/html/_static/minus.png +0 -0
  193. data/vendor/local/share/groonga/doc/ja/html/_static/plus.png +0 -0
  194. data/vendor/local/share/groonga/doc/ja/html/_static/pygments.css +0 -61
  195. data/vendor/local/share/groonga/doc/ja/html/_static/searchtools.js +0 -518
  196. data/vendor/local/share/groonga/doc/ja/html/_static/sidebar.js +0 -147
  197. data/vendor/local/share/groonga/doc/ja/html/_static/underscore.js +0 -16
  198. data/vendor/local/share/groonga/doc/ja/html/characteristic.html +0 -162
  199. data/vendor/local/share/groonga/doc/ja/html/commands.html +0 -139
  200. data/vendor/local/share/groonga/doc/ja/html/commands/cache_limit.html +0 -173
  201. data/vendor/local/share/groonga/doc/ja/html/commands/check.html +0 -285
  202. data/vendor/local/share/groonga/doc/ja/html/commands/clearlock.html +0 -180
  203. data/vendor/local/share/groonga/doc/ja/html/commands/column_create.html +0 -210
  204. data/vendor/local/share/groonga/doc/ja/html/commands/column_list.html +0 -220
  205. data/vendor/local/share/groonga/doc/ja/html/commands/column_remove.html +0 -183
  206. data/vendor/local/share/groonga/doc/ja/html/commands/define_selector.html +0 -221
  207. data/vendor/local/share/groonga/doc/ja/html/commands/defrag.html +0 -177
  208. data/vendor/local/share/groonga/doc/ja/html/commands/delete.html +0 -182
  209. data/vendor/local/share/groonga/doc/ja/html/commands/dump.html +0 -177
  210. data/vendor/local/share/groonga/doc/ja/html/commands/load.html +0 -208
  211. data/vendor/local/share/groonga/doc/ja/html/commands/log_level.html +0 -187
  212. data/vendor/local/share/groonga/doc/ja/html/commands/log_put.html +0 -190
  213. data/vendor/local/share/groonga/doc/ja/html/commands/log_reopen.html +0 -188
  214. data/vendor/local/share/groonga/doc/ja/html/commands/quit.html +0 -156
  215. data/vendor/local/share/groonga/doc/ja/html/commands/select.html +0 -331
  216. data/vendor/local/share/groonga/doc/ja/html/commands/shutdown.html +0 -156
  217. data/vendor/local/share/groonga/doc/ja/html/commands/status.html +0 -179
  218. data/vendor/local/share/groonga/doc/ja/html/commands/suggest.html +0 -191
  219. data/vendor/local/share/groonga/doc/ja/html/commands/table_create.html +0 -222
  220. data/vendor/local/share/groonga/doc/ja/html/commands/table_list.html +0 -202
  221. data/vendor/local/share/groonga/doc/ja/html/commands/table_remove.html +0 -173
  222. data/vendor/local/share/groonga/doc/ja/html/commands/view_add.html +0 -175
  223. data/vendor/local/share/groonga/doc/ja/html/commands_not_implemented/add.html +0 -180
  224. data/vendor/local/share/groonga/doc/ja/html/commands_not_implemented/get.html +0 -161
  225. data/vendor/local/share/groonga/doc/ja/html/commands_not_implemented/set.html +0 -182
  226. data/vendor/local/share/groonga/doc/ja/html/developer.html +0 -118
  227. data/vendor/local/share/groonga/doc/ja/html/developer/com.html +0 -136
  228. data/vendor/local/share/groonga/doc/ja/html/developer/document.html +0 -159
  229. data/vendor/local/share/groonga/doc/ja/html/developer/query.html +0 -336
  230. data/vendor/local/share/groonga/doc/ja/html/developer/test.html +0 -220
  231. data/vendor/local/share/groonga/doc/ja/html/execfile.html +0 -370
  232. data/vendor/local/share/groonga/doc/ja/html/expr.html +0 -157
  233. data/vendor/local/share/groonga/doc/ja/html/functions.html +0 -122
  234. data/vendor/local/share/groonga/doc/ja/html/functions/edit_distance.html +0 -162
  235. data/vendor/local/share/groonga/doc/ja/html/functions/geo_distance.html +0 -170
  236. data/vendor/local/share/groonga/doc/ja/html/functions/geo_in_circle.html +0 -173
  237. data/vendor/local/share/groonga/doc/ja/html/functions/geo_in_rectangle.html +0 -172
  238. data/vendor/local/share/groonga/doc/ja/html/functions/now.html +0 -152
  239. data/vendor/local/share/groonga/doc/ja/html/functions/rand.html +0 -159
  240. data/vendor/local/share/groonga/doc/ja/html/genindex.html +0 -227
  241. data/vendor/local/share/groonga/doc/ja/html/grnslap.html +0 -183
  242. data/vendor/local/share/groonga/doc/ja/html/grntest.html +0 -368
  243. data/vendor/local/share/groonga/doc/ja/html/http.html +0 -163
  244. data/vendor/local/share/groonga/doc/ja/html/index.html +0 -291
  245. data/vendor/local/share/groonga/doc/ja/html/install.html +0 -228
  246. data/vendor/local/share/groonga/doc/ja/html/news.html +0 -310
  247. data/vendor/local/share/groonga/doc/ja/html/objects.inv +0 -0
  248. data/vendor/local/share/groonga/doc/ja/html/process.html +0 -120
  249. data/vendor/local/share/groonga/doc/ja/html/pseudo_column.html +0 -147
  250. data/vendor/local/share/groonga/doc/ja/html/reference.html +0 -174
  251. data/vendor/local/share/groonga/doc/ja/html/search.html +0 -96
  252. data/vendor/local/share/groonga/doc/ja/html/searchindex.js +0 -1
  253. data/vendor/local/share/groonga/doc/ja/html/tutorial.html +0 -172
  254. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial01.html +0 -388
  255. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial02.html +0 -214
  256. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial03.html +0 -183
  257. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial04.html +0 -212
  258. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial05.html +0 -169
  259. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial06.html +0 -209
  260. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial07.html +0 -212
  261. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial08.html +0 -139
  262. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial09.html +0 -114
  263. data/vendor/local/share/groonga/doc/ja/html/tutorial/tutorial10.html +0 -458
  264. data/vendor/local/share/groonga/doc/ja/html/type.html +0 -217
  265. data/vendor/local/share/groonga/doc/ja/source/__init__.py +0 -0
  266. data/vendor/local/share/groonga/doc/ja/source/characteristic.txt +0 -56
  267. data/vendor/local/share/groonga/doc/ja/source/commands.txt +0 -10
  268. data/vendor/local/share/groonga/doc/ja/source/commands/cache_limit.txt +0 -52
  269. data/vendor/local/share/groonga/doc/ja/source/commands/check.txt +0 -164
  270. data/vendor/local/share/groonga/doc/ja/source/commands/clearlock.txt +0 -61
  271. data/vendor/local/share/groonga/doc/ja/source/commands/column_create.txt +0 -93
  272. data/vendor/local/share/groonga/doc/ja/source/commands/column_list.txt +0 -97
  273. data/vendor/local/share/groonga/doc/ja/source/commands/column_remove.txt +0 -58
  274. data/vendor/local/share/groonga/doc/ja/source/commands/define_selector.txt +0 -114
  275. data/vendor/local/share/groonga/doc/ja/source/commands/defrag.txt +0 -57
  276. data/vendor/local/share/groonga/doc/ja/source/commands/delete.txt +0 -68
  277. data/vendor/local/share/groonga/doc/ja/source/commands/dump.txt +0 -62
  278. data/vendor/local/share/groonga/doc/ja/source/commands/load.txt +0 -98
  279. data/vendor/local/share/groonga/doc/ja/source/commands/log_level.txt +0 -65
  280. data/vendor/local/share/groonga/doc/ja/source/commands/log_put.txt +0 -69
  281. data/vendor/local/share/groonga/doc/ja/source/commands/log_reopen.txt +0 -66
  282. data/vendor/local/share/groonga/doc/ja/source/commands/quit.txt +0 -38
  283. data/vendor/local/share/groonga/doc/ja/source/commands/select.txt +0 -247
  284. data/vendor/local/share/groonga/doc/ja/source/commands/shutdown.txt +0 -38
  285. data/vendor/local/share/groonga/doc/ja/source/commands/status.txt +0 -59
  286. data/vendor/local/share/groonga/doc/ja/source/commands/table_create.txt +0 -111
  287. data/vendor/local/share/groonga/doc/ja/source/commands/table_list.txt +0 -87
  288. data/vendor/local/share/groonga/doc/ja/source/commands/table_remove.txt +0 -50
  289. data/vendor/local/share/groonga/doc/ja/source/commands/view_add.txt +0 -53
  290. data/vendor/local/share/groonga/doc/ja/source/commands_not_implemented/add.txt +0 -102
  291. data/vendor/local/share/groonga/doc/ja/source/commands_not_implemented/get.txt +0 -78
  292. data/vendor/local/share/groonga/doc/ja/source/commands_not_implemented/set.txt +0 -103
  293. data/vendor/local/share/groonga/doc/ja/source/conf.py +0 -265
  294. data/vendor/local/share/groonga/doc/ja/source/developer.txt +0 -10
  295. data/vendor/local/share/groonga/doc/ja/source/developer/com.txt +0 -18
  296. data/vendor/local/share/groonga/doc/ja/source/developer/document.txt +0 -38
  297. data/vendor/local/share/groonga/doc/ja/source/developer/query.txt +0 -212
  298. data/vendor/local/share/groonga/doc/ja/source/developer/test.txt +0 -114
  299. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-1.log +0 -6
  300. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-10.log +0 -5
  301. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-11.log +0 -5
  302. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-12.log +0 -5
  303. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-13.log +0 -5
  304. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-14.log +0 -9
  305. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-15.log +0 -5
  306. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-16.log +0 -5
  307. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-17.log +0 -5
  308. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-2.log +0 -5
  309. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-3.log +0 -5
  310. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-4.log +0 -7
  311. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-5.log +0 -5
  312. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-6.log +0 -5
  313. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-7.log +0 -16
  314. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-8.log +0 -5
  315. data/vendor/local/share/groonga/doc/ja/source/example/tutorial01-9.log +0 -5
  316. data/vendor/local/share/groonga/doc/ja/source/example/tutorial02-1.log +0 -8
  317. data/vendor/local/share/groonga/doc/ja/source/example/tutorial02-2.log +0 -6
  318. data/vendor/local/share/groonga/doc/ja/source/example/tutorial02-3.log +0 -12
  319. data/vendor/local/share/groonga/doc/ja/source/example/tutorial03-1.log +0 -18
  320. data/vendor/local/share/groonga/doc/ja/source/example/tutorial03-2.log +0 -10
  321. data/vendor/local/share/groonga/doc/ja/source/example/tutorial03-3.log +0 -10
  322. data/vendor/local/share/groonga/doc/ja/source/example/tutorial04-1.log +0 -5
  323. data/vendor/local/share/groonga/doc/ja/source/example/tutorial04-2.log +0 -7
  324. data/vendor/local/share/groonga/doc/ja/source/example/tutorial04-3.log +0 -7
  325. data/vendor/local/share/groonga/doc/ja/source/example/tutorial04-4.log +0 -13
  326. data/vendor/local/share/groonga/doc/ja/source/example/tutorial04-5.log +0 -5
  327. data/vendor/local/share/groonga/doc/ja/source/example/tutorial04-6.log +0 -5
  328. data/vendor/local/share/groonga/doc/ja/source/example/tutorial04-7.log +0 -5
  329. data/vendor/local/share/groonga/doc/ja/source/example/tutorial05-1.log +0 -24
  330. data/vendor/local/share/groonga/doc/ja/source/example/tutorial05-2.log +0 -5
  331. data/vendor/local/share/groonga/doc/ja/source/example/tutorial05-3.log +0 -5
  332. data/vendor/local/share/groonga/doc/ja/source/example/tutorial05-4.log +0 -5
  333. data/vendor/local/share/groonga/doc/ja/source/example/tutorial05-5.log +0 -5
  334. data/vendor/local/share/groonga/doc/ja/source/example/tutorial05-6.log +0 -5
  335. data/vendor/local/share/groonga/doc/ja/source/example/tutorial06-1.log +0 -25
  336. data/vendor/local/share/groonga/doc/ja/source/example/tutorial06-2.log +0 -9
  337. data/vendor/local/share/groonga/doc/ja/source/example/tutorial06-3.log +0 -21
  338. data/vendor/local/share/groonga/doc/ja/source/example/tutorial06-4.log +0 -7
  339. data/vendor/local/share/groonga/doc/ja/source/example/tutorial06-5.log +0 -5
  340. data/vendor/local/share/groonga/doc/ja/source/example/tutorial07-1.log +0 -22
  341. data/vendor/local/share/groonga/doc/ja/source/example/tutorial07-2.log +0 -9
  342. data/vendor/local/share/groonga/doc/ja/source/example/tutorial07-3.log +0 -20
  343. data/vendor/local/share/groonga/doc/ja/source/example/tutorial07-4.log +0 -9
  344. data/vendor/local/share/groonga/doc/ja/source/example/tutorial08-1.log +0 -14
  345. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-1.log +0 -5
  346. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-10.log +0 -5
  347. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-2.log +0 -5
  348. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-3.log +0 -5
  349. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-4.log +0 -5
  350. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-5.log +0 -5
  351. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-6.log +0 -5
  352. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-7.log +0 -5
  353. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-8.log +0 -5
  354. data/vendor/local/share/groonga/doc/ja/source/example/tutorial10-9.log +0 -5
  355. data/vendor/local/share/groonga/doc/ja/source/execfile.txt +0 -226
  356. data/vendor/local/share/groonga/doc/ja/source/expr.txt +0 -43
  357. data/vendor/local/share/groonga/doc/ja/source/functions.txt +0 -10
  358. data/vendor/local/share/groonga/doc/ja/source/functions/edit_distance.txt +0 -48
  359. data/vendor/local/share/groonga/doc/ja/source/functions/geo_distance.txt +0 -51
  360. data/vendor/local/share/groonga/doc/ja/source/functions/geo_in_circle.txt +0 -54
  361. data/vendor/local/share/groonga/doc/ja/source/functions/geo_in_rectangle.txt +0 -55
  362. data/vendor/local/share/groonga/doc/ja/source/functions/now.txt +0 -34
  363. data/vendor/local/share/groonga/doc/ja/source/functions/rand.txt +0 -41
  364. data/vendor/local/share/groonga/doc/ja/source/grnslap.txt +0 -64
  365. data/vendor/local/share/groonga/doc/ja/source/grntest.txt +0 -259
  366. data/vendor/local/share/groonga/doc/ja/source/http.txt +0 -52
  367. data/vendor/local/share/groonga/doc/ja/source/index.txt +0 -21
  368. data/vendor/local/share/groonga/doc/ja/source/install.txt +0 -114
  369. data/vendor/local/share/groonga/doc/ja/source/news.txt +0 -199
  370. data/vendor/local/share/groonga/doc/ja/source/process.txt +0 -12
  371. data/vendor/local/share/groonga/doc/ja/source/pseudo_column.txt +0 -38
  372. data/vendor/local/share/groonga/doc/ja/source/rdoc.py +0 -762
  373. data/vendor/local/share/groonga/doc/ja/source/reference.txt +0 -14
  374. data/vendor/local/share/groonga/doc/ja/source/tutorial.txt +0 -10
  375. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial01.txt +0 -293
  376. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial02.txt +0 -100
  377. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial03.txt +0 -72
  378. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial04.txt +0 -111
  379. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial05.txt +0 -65
  380. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial06.txt +0 -91
  381. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial07.txt +0 -92
  382. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial08.txt +0 -53
  383. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial09.txt +0 -9
  384. data/vendor/local/share/groonga/doc/ja/source/tutorial/tutorial10.txt +0 -486
  385. data/vendor/local/share/groonga/doc/ja/source/type.txt +0 -118
  386. data/vendor/local/share/groonga/doc/ja/source/update_execution_example.py +0 -113
  387. data/vendor/local/share/man/man1/groonga.1 +0 -5498
@@ -0,0 +1,212 @@
1
+ # Wikipedia data: http://download.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2
2
+
3
+ require 'time'
4
+ require 'fileutils'
5
+ require 'groonga'
6
+
7
+ require 'nokogiri'
8
+
9
+ class WikipediaExtractor
10
+ def initialize(listener)
11
+ @listener = listener
12
+ end
13
+
14
+ def extract(input)
15
+ extractor = Extractor.new(@listener)
16
+ parser = Nokogiri::XML::SAX::Parser.new(extractor)
17
+ parser.parse(input)
18
+ end
19
+
20
+ class Extractor
21
+ def initialize(listener)
22
+ @listener = listener
23
+ @name_stack = []
24
+ @text_stack = []
25
+ @contributor_stack = []
26
+ @page = {}
27
+ end
28
+
29
+ def start_document
30
+ end
31
+
32
+ def end_document
33
+ end
34
+
35
+ def start_element_namespace(name, attrs=[], prefix=nil, uri=nil, ns=[])
36
+ @name_stack << name
37
+ @text_stack << ""
38
+ case @name_stack.join(".")
39
+ when "mediawiki.page"
40
+ @page = {}
41
+ when "mediawiki.page.revision.contributor"
42
+ @contributor_stack << {}
43
+ end
44
+ end
45
+
46
+ def end_element_namespace(name, prefix=nil, uri=nil)
47
+ case @name_stack.join(".")
48
+ when "mediawiki.page"
49
+ @listener.page(@page)
50
+ when "mediawiki.page.title"
51
+ title = @text_stack.last
52
+ @page[:title] = @listener.title(title) || title
53
+ when "mediawiki.page.revision.timestamp"
54
+ timestamp = Time.parse(@text_stack.last)
55
+ @page[:timestamp] = @listener.timestamp(timestamp) || timestamp
56
+ when "mediawiki.page.revision.contributor"
57
+ contributor = @contributor_stack.pop
58
+ @page[:contributor] = @listener.contributor(contributor) || contributor
59
+ when "mediawiki.page.revision.contributor.id"
60
+ @contributor_stack.last[:id] = Integer(@text_stack.last)
61
+ when "mediawiki.page.revision.contributor.username"
62
+ @contributor_stack.last[:name] = @text_stack.last
63
+ when "mediawiki.page.revision.text"
64
+ content = @text_stack.last
65
+ @page[:content] = @listener.content(content) || content
66
+ end
67
+ @name_stack.pop
68
+ @text_stack.pop
69
+ end
70
+
71
+ def characters(string)
72
+ elements_without_interested_text = [
73
+ "mediawiki", "siteinfo", "case",
74
+ "namespaces", "revisions",
75
+ "contributor",
76
+ ]
77
+ return if elements_without_interested_text.include?(@name_stack.last)
78
+ @text_stack.last << string
79
+ end
80
+
81
+ def xmldecl(*arguments, &block)
82
+ end
83
+
84
+ def comment(string)
85
+ end
86
+
87
+ def warning(string)
88
+ end
89
+
90
+ def error(string)
91
+ end
92
+
93
+ def cdata_block(string)
94
+ end
95
+ end
96
+ end
97
+
98
+ class WikipediaImporter
99
+ def initialize(groonga_loader)
100
+ @groonga_loader = groonga_loader
101
+ end
102
+
103
+ def title(title)
104
+ end
105
+
106
+ def timestamp(timestamp)
107
+ end
108
+
109
+ def contributor(contributor)
110
+ end
111
+
112
+ def content(content)
113
+ end
114
+
115
+ def page(page)
116
+ @groonga_loader.load(page)
117
+ end
118
+ end
119
+
120
+ module TimeDrilldownable
121
+ def define_time_columns(table)
122
+ table.int32("year")
123
+ table.int32("month")
124
+ table.short_text("date")
125
+ table.int32("wday")
126
+ table.int32("hour")
127
+ end
128
+
129
+ def add_time(table, key, time)
130
+ table[key]["year"] = time.year
131
+ table[key]["month"] = time.month
132
+ table[key]["date"] = time.strftime("%m/%d")
133
+ table[key]["wday"] = time.wday
134
+ table[key]["hour"] = time.hour
135
+ end
136
+ end
137
+
138
+ class GroongaLoader
139
+ include TimeDrilldownable
140
+
141
+ def initialize
142
+ FileUtils.rm_rf("/tmp/wikipedia-db")
143
+ FileUtils.mkdir_p("/tmp/wikipedia-db")
144
+ @context = Groonga::Context.new
145
+ @context.create_database("/tmp/wikipedia-db/db")
146
+
147
+ Groonga::Schema.define(:context => @context) do |schema|
148
+ schema.create_table("Users", :type => :hash, :key_type => "Int64") do |table|
149
+ table.short_text("name")
150
+ end
151
+
152
+ schema.create_table("Documents", :type => :patricia_trie, :key_type => "ShortText") do |table|
153
+ table.long_text("content")
154
+ table.time("timestamp")
155
+ define_time_columns(table)
156
+ table.reference("last_contributor", "Users")
157
+ table.column("links", "Documents", :type => :vector)
158
+ end
159
+
160
+ schema.create_table("Terms", :type => :hash, :default_tokenizer => "TokenBigram") do |table|
161
+ table.index("Documents._key")
162
+ table.index("Documents.content")
163
+ end
164
+ end
165
+ @documents = @context["Documents"]
166
+ @users = @context["Users"]
167
+ @terms = @context["Terms"]
168
+ end
169
+
170
+ LOCK_TIMEOUT_SECONDS = 10
171
+ def lock
172
+ @context.database.lock(:timeout => LOCK_TIMEOUT_SECONDS * 1000) do
173
+ yield
174
+ end
175
+ end
176
+
177
+ def load(page)
178
+ lock do
179
+ do_load(page)
180
+ end
181
+ end
182
+
183
+ def do_load(page)
184
+ content = page.delete(:content)
185
+ timestamp = page.delete(:timestamp)
186
+ title = page.delete(:title)
187
+ contributor = page.delete(:contributor)
188
+
189
+ puts "loading: #{title}"
190
+ @documents.add(title, :content => content, :timestamp => timestamp)
191
+ load_links(title, content)
192
+ add_time(@documents, title, timestamp)
193
+
194
+ if not contributor.empty?
195
+ @documents.add(title, :last_contributor => contributor[:id])
196
+ @users[contributor[:id]][:name] = contributor[:name]
197
+ end
198
+ end
199
+
200
+ def load_links(title, content)
201
+ links = content.scan(/\[\[.*?\]\]/)
202
+ links = links.collect do |link|
203
+ link.sub(/\A\[\[/, '').sub(/\]\]\z/, '').sub(/\|[^\|]+\z/, '')
204
+ end
205
+ @documents.add(title, :links => links)
206
+ end
207
+ end
208
+
209
+ if __FILE__ == $0
210
+ extractor = WikipediaExtractor.new(WikipediaImporter.new(GroongaLoader.new))
211
+ extractor.extract(ARGF)
212
+ end
File without changes
@@ -0,0 +1,213 @@
1
+ require 'fileutils'
2
+ require 'shellwords'
3
+
4
+ require 'groonga'
5
+
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'create-wikipedia-database'
8
+
9
+ class SampleRecords
10
+ def initialize(record_count)
11
+ @record_count = record_count
12
+ @current_count = 0
13
+ @records = []
14
+
15
+ initialize_sample_records
16
+ end
17
+
18
+ def initialize_sample_records
19
+ extractor = WikipediaExtractor.new(WikipediaImporter.new(self))
20
+ #@records = @record_count.times.collect do
21
+ # create_random_item
22
+ #end
23
+ catch(:stop_extract) do
24
+ extractor.extract(ARGF)
25
+ end
26
+ end
27
+
28
+ def load(page)
29
+ @current_count += 1
30
+ record = {
31
+ :_key => page[:title],
32
+ :content => page[:content],
33
+ }
34
+ #pp record
35
+ @records << record
36
+ throw :stop_extract if @current_count == @record_count
37
+ end
38
+
39
+ def values(count=nil)
40
+ count ||= @record_count
41
+
42
+ if count == 1
43
+ [first_record]
44
+ else
45
+ @records[0, count - 1] + [first_record]
46
+ end
47
+ end
48
+
49
+ def first_record
50
+ @records.first
51
+ end
52
+
53
+ def each(*arguments, &block)
54
+ values.each(*arguments, &block)
55
+ end
56
+
57
+ def n_records(count)
58
+ values(count)
59
+ end
60
+
61
+ def create_random_item
62
+ {"_key" => "ryoqun"}
63
+ end
64
+ end
65
+
66
+ class RepeatLoadRunner
67
+ DATABASE_DIRECTORY = "/tmp/repeat-overwrite"
68
+
69
+ def initialize(sample_records, options=nil)
70
+ @options = options || {}
71
+ @context = Groonga::Context.new(:encoding => :none)
72
+ @sample_records = sample_records
73
+ end
74
+
75
+ DEFAULT_REPEAT_COUNT = 1
76
+ DEFAULT_RECORD_COUNT = 1
77
+ def repeat_count
78
+ @options[:repeat_count] || DEFAULT_REPEAT_COUNT
79
+ end
80
+
81
+ def record_count
82
+ @options[:record_count] || DEFAULT_RECORD_COUNT
83
+ end
84
+
85
+ def with_index?
86
+ @options[:with_index]
87
+ end
88
+
89
+ def database_directory
90
+ DATABASE_DIRECTORY
91
+ end
92
+
93
+ def database_path
94
+ "#{database_directory}/db"
95
+ end
96
+
97
+ def setup_database
98
+ FileUtils.rm_rf(database_directory)
99
+ FileUtils.mkdir_p(database_directory)
100
+
101
+ @context.create_database(database_path)
102
+ Groonga::Schema.define(:context => @context) do |schema|
103
+ schema.create_table("Contents", :type => :hash, :key_type => "ShortText") do |table|
104
+ table.long_text("content")
105
+ end
106
+
107
+ if with_index?
108
+ schema.create_table("Terms", :type => :hash, :default_tokenizer => "TokenBigram") do |table|
109
+ table.index("Contents._key")
110
+ table.index("Contents.content")
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ def run
117
+ setup_database
118
+
119
+ before_load
120
+ add_record
121
+ after_load
122
+ end
123
+
124
+ private
125
+ def add_record
126
+ puts "loading..."
127
+ repeat_count.times do |count|
128
+ add_record_via_load_command
129
+ if repeat_count != 1 and count.zero?
130
+ after_first_load
131
+ end
132
+ end
133
+ puts "... (#{repeat_count} times repeated)"
134
+ puts
135
+ end
136
+
137
+ def add_record_via_load_command
138
+ puts "iteration: loading #{record_count} records"
139
+ count = 0
140
+ @sample_records.n_records(record_count).each do |record|
141
+ mangle_record(record)
142
+
143
+ #pp record
144
+ command = "load --table Contents --input_type json --values '#{JSON.generate(record).gsub(/\'/, '').gsub(/\"/, '\\\"')}'"
145
+ #puts command
146
+ @context.send(command)
147
+ if record_count != 1 and count.zero?
148
+ after_first_load
149
+ end
150
+ count += 1
151
+ end
152
+ end
153
+
154
+ def mangle_record(record)
155
+ record[:content] = record[:content][0, 400]
156
+ record[:_key] = :FIXED_KEY
157
+ end
158
+
159
+ def before_load
160
+ puts "before load:"
161
+ measure_database_size
162
+ puts
163
+ end
164
+
165
+ def after_first_load
166
+ puts "after first load:"
167
+ measure_database_size
168
+ puts
169
+ end
170
+
171
+ def after_load
172
+ puts "after load:"
173
+ measure_database_size
174
+ puts
175
+ end
176
+
177
+ def measure_database_size
178
+ #measure_apparent_size
179
+ measure_actual_size
180
+ end
181
+
182
+ def measure_apparent_size
183
+ puts "apparent disk usage:"
184
+ puts execute_du("--apparent-size")
185
+ end
186
+
187
+ def measure_actual_size
188
+ puts "actual disk usage:"
189
+ puts execute_du
190
+ end
191
+
192
+ def execute_du(options=nil)
193
+ `sync`
194
+ `find #{database_directory} -type f -print0 | xargs -0 du --human-readable #{options.to_s} | sort -k 2 | uniq`
195
+ end
196
+ end
197
+
198
+ sample_records = SampleRecords.new(1000)
199
+
200
+ #puts "load one record, repeat one time"
201
+ #RepeatLoadRunner.new(sample_records).run
202
+
203
+ #puts "load one record, repeat 100 time"
204
+ #RepeatLoadRunner.new(sample_records, :repeat_count => 100).run
205
+
206
+ #puts "load one record, repeat 100 time with index column defined"
207
+ #RepeatLoadRunner.new(sample_records, :repeat_count => 100, :with_index => true).run
208
+
209
+ puts "load 100 records, repeat 1 time"
210
+ RepeatLoadRunner.new(sample_records, :record_count => 100).run
211
+
212
+ puts "load 100 records, repeat 1 time with index column defined"
213
+ RepeatLoadRunner.new(sample_records, :record_count => 100, :with_index => true).run
@@ -0,0 +1,1052 @@
1
+ #encoding: UTF-8
2
+
3
+ require 'benchmark'
4
+ require 'shellwords'
5
+ require 'optparse'
6
+
7
+ require 'groonga'
8
+
9
+ Groonga::Logger.query_log_path = "/tmp/query.log"
10
+
11
+ module ColumnTokenizer
12
+ def tokenize_column_list(column_list)
13
+ tokens = column_list.split(/[\s,]/)
14
+ tokens.reject!(&:empty?)
15
+ tokens.select! do |token|
16
+ token == "*" || token =~ /[A-Za-z0-9_]/
17
+ end
18
+ tokens.each do |token|
19
+ unless token == "*"
20
+ token.sub!(/[^A-Za-z0-9_]\z/, '')
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ class Query
27
+ attr_reader :options
28
+ attr_accessor :original_log_entry
29
+ def initialize(options)
30
+ @options = options
31
+ end
32
+
33
+ def table_name
34
+ @options[:table]
35
+ end
36
+
37
+ def match_columns
38
+ #raise "unsupported: #{@options[:match_columns].inspect}" if @options[:match_columns] =~ /\b/ # XXX
39
+
40
+ @options[:match_columns]
41
+ end
42
+
43
+ def filter
44
+ if match_columns and @options[:query]
45
+ #raise "unsupported" if @options[:filter]
46
+ @options[:query]
47
+ else
48
+ @options[:filter]
49
+ end
50
+ end
51
+
52
+ def limit
53
+ if @options[:limit]
54
+ @options[:limit].to_i
55
+ else
56
+ nil
57
+ end
58
+ end
59
+
60
+ def offset
61
+ if @options[:offset]
62
+ @options[:offset].to_i
63
+ else
64
+ nil
65
+ end
66
+ end
67
+
68
+ def sort_by
69
+ if @options[:sortby]
70
+ @options[:sortby]
71
+ else
72
+ nil
73
+ end
74
+ end
75
+
76
+ def output_columns
77
+ if @options[:output_columns]
78
+ @options[:output_columns]
79
+ else
80
+ nil
81
+ end
82
+ end
83
+
84
+ def drilldown_columns
85
+ if @options[:drilldown]
86
+ @options[:drilldown]
87
+ else
88
+ nil
89
+ end
90
+ end
91
+
92
+ def drilldown_limit
93
+ if @options[:drilldown_limit]
94
+ @options[:drilldown_limit].to_i
95
+ else
96
+ nil
97
+ end
98
+ end
99
+
100
+ def drilldown_offset
101
+ if @options[:drilldown_offset]
102
+ @options[:drilldown_offset].to_i
103
+ else
104
+ nil
105
+ end
106
+ end
107
+
108
+ def drilldown_sort_by
109
+ if @options[:drilldown_sortby]
110
+ @options[:drilldown_sortby]
111
+ else
112
+ nil
113
+ end
114
+ end
115
+
116
+ def drilldown_output_columns
117
+ if @options[:drilldown_output_columns]
118
+ @options[:drilldown_output_columns]
119
+ else
120
+ nil
121
+ end
122
+ end
123
+
124
+ def parameters
125
+ @options.dup.tap do |options|
126
+ options.delete(:table)
127
+ end
128
+ end
129
+
130
+ class GroongaLogParser
131
+ def initialize(log)
132
+ @log = log
133
+ @tokens = []
134
+ @parameter_list = []
135
+ @parameters = {}
136
+ end
137
+
138
+ def parse
139
+ tokenize
140
+ build_parameter_list
141
+ build_parameters
142
+ create_query
143
+ end
144
+
145
+ class << self
146
+ def parse(log)
147
+ new(log).parse
148
+ end
149
+ end
150
+
151
+ private
152
+ def next_token(token)
153
+ @tokens << token
154
+ ""
155
+ end
156
+
157
+ def tokenize
158
+ escape = nil
159
+ litaral = nil
160
+ token = ""
161
+
162
+ @tokens = Shellwords.split(@log)
163
+ @tokens = @tokens.reject(&:empty?)
164
+ end
165
+
166
+ IMPLICIT_PARAMETER_ORDER = [
167
+ :table,
168
+ :match_columns,
169
+ :query,
170
+ :filter,
171
+ :scorer,
172
+ :sortby,
173
+ :output_columns,
174
+ :offset,
175
+ :limit,
176
+ :drilldown,
177
+ :drilldown_sortby,
178
+ :drilldwon_output_columns,
179
+ :drilldown_offset,
180
+ :drilldown_limit,
181
+ :cache,
182
+ :match_escalation_threshold,
183
+ ]
184
+
185
+ NAMED_PARAMETER_PREFIX = /\A--/
186
+
187
+ def build_parameter_list
188
+ command, parameter_tokens = @tokens.shift, @tokens
189
+ raise "command is not \"select\": #{command.inspect}" unless command == "select"
190
+
191
+ parameter_name = nil
192
+ parameter_tokens.each do |token|
193
+ if token =~ NAMED_PARAMETER_PREFIX
194
+ raise "bad" unless parameter_name.nil?
195
+ parameter_name = token
196
+ elsif parameter_name
197
+ @parameter_list << [parameter_name, token]
198
+ parameter_name = nil
199
+ else
200
+ @parameter_list << token
201
+ end
202
+ end
203
+ end
204
+
205
+ def build_parameters
206
+ index = 0
207
+ @parameter_list.each do |parameter|
208
+ case parameter
209
+ when Array
210
+ name, value = parameter
211
+ @parameters[to_parameter_symbol(name)] = value
212
+ else
213
+ @parameters[IMPLICIT_PARAMETER_ORDER[index]] = parameter
214
+ index += 1
215
+ end
216
+ end
217
+ end
218
+
219
+ def to_parameter_symbol(name)
220
+ name.sub(NAMED_PARAMETER_PREFIX, '').to_sym
221
+ end
222
+
223
+ def create_query
224
+ query = Query.new(@parameters)
225
+ query.original_log_entry = @log
226
+ query
227
+ end
228
+ end
229
+
230
+ class << self
231
+ def parse_groonga_query_log(log)
232
+ GroongaLogParser.parse(log)
233
+ end
234
+ end
235
+ end
236
+
237
+ class Configuration
238
+ attr_accessor :database_path
239
+ end
240
+
241
+ class Selector
242
+ attr_reader :context, :database_path
243
+ def initialize(context, database_path)
244
+ @context = context
245
+ @database_path = database_path
246
+ @database = @context.open_database(@database_path)
247
+ end
248
+
249
+ def select(query)
250
+ raise "implement"
251
+ end
252
+ end
253
+
254
+ class SelectorByCommand < Selector
255
+ def select(query)
256
+ parameters = query.parameters.merge(:cache => :no)
257
+ parameters[:sortby] ||= :_id
258
+ parameters[:drilldown_sortby] ||= :_key
259
+ result = @context.select(query.table_name, parameters)
260
+ CommandResult.new(result)
261
+ end
262
+ end
263
+
264
+ class SelectorByMethod < Selector
265
+ include ColumnTokenizer
266
+
267
+ def select(query)
268
+ table = @context[query.table_name]
269
+ filter = query.filter
270
+ if query.match_columns
271
+ default_column = table.column(query.match_columns)
272
+ end
273
+
274
+ result = do_select(filter, table, default_column)
275
+ sorted_result = sort(query, result)
276
+ formatted_result = format(query, sorted_result || result)
277
+ drilldown_results = drilldown(query, result)
278
+
279
+ MethodResult.new(result, sorted_result, formatted_result, drilldown_results)
280
+ end
281
+
282
+ def do_select(filter, table, default_column)
283
+ if filter
284
+ options = {
285
+ :syntax => :script
286
+ }
287
+ if default_column
288
+ options[:default_column] = default_column
289
+ options[:syntax] = :query
290
+ end
291
+
292
+ table.select(filter, options)
293
+ else
294
+ table.select
295
+ end
296
+ end
297
+
298
+ DEFAULT_LIMIT = 10
299
+ DEFAULT_DRILLDOWN_LIMIT = DEFAULT_LIMIT
300
+
301
+ def sort(query, result)
302
+ if needs_sort?(query)
303
+ sort_key = sort_key(query.sort_by)
304
+ limit = query.limit || DEFAULT_LIMIT
305
+ offset = query.offset
306
+
307
+ window_options = create_window_options(limit, offset)
308
+ sorted_result = result.sort(sort_key, window_options).collect do |record|
309
+ record.key
310
+ end
311
+ end
312
+ end
313
+
314
+ def drilldown_sort(query, result)
315
+ sort_key = sort_key(query.drilldown_sort_by || "_key")
316
+ limit = query.drilldown_limit || DEFAULT_DRILLDOWN_LIMIT
317
+ offset = query.drilldown_offset
318
+
319
+ window_options = create_window_options(limit, offset)
320
+
321
+ sorted_result = result.sort(sort_key, window_options).collect do |record|
322
+ record
323
+ end
324
+ end
325
+
326
+ DEFAULT_OUTPUT_COLUMNS = "_id, _key, *"
327
+ DEFAULT_DRILLDOWN_OUTPUT_COLUMNS = "_key, _nsubrecs"
328
+
329
+ def format(query, result)
330
+ columns = query.output_columns || DEFAULT_OUTPUT_COLUMNS
331
+ format_result(result, columns)
332
+ end
333
+
334
+ def drilldown_format(query, result)
335
+ columns = query.drilldown_output_columns || DEFAULT_DRILLDOWN_OUTPUT_COLUMNS
336
+ format_result(result, columns)
337
+ end
338
+
339
+ def drilldown(query, result)
340
+ if needs_drilldown?(query)
341
+ drilldown_results = drilldown_result(result, query.drilldown_columns, query)
342
+ end
343
+ end
344
+
345
+ def drilldown_result(result, drilldown_columns, query)
346
+ columns = tokenize_column_list(drilldown_columns).uniq
347
+ columns.collect do |column|
348
+ drilldown_result = do_group(result, column)
349
+ sorted_drilldown_result = drilldown_sort(query, drilldown_result)
350
+ formatted_drilldown_result = drilldown_format(query, sorted_drilldown_result || drilldown_result)
351
+
352
+ {
353
+ :column => column,
354
+ :result => drilldown_result,
355
+ :sort => sorted_drilldown_result,
356
+ :format => formatted_drilldown_result,
357
+ }
358
+ end
359
+ end
360
+
361
+ def do_group(result, column)
362
+ result.group(column)
363
+ end
364
+
365
+ def needs_sort?(query)
366
+ (query.limit.nil? or query.limit >= 0) or query.offset or query.sort_by
367
+ end
368
+
369
+ def needs_drilldown?(query)
370
+ query.drilldown_columns
371
+ end
372
+
373
+ DESCENDING_ORDER_PREFIX = /\A-/
374
+ def sort_key(sort_by)
375
+ if sort_by
376
+ build_sort_key(sort_by)
377
+ else
378
+ default_sort_key
379
+ end
380
+ end
381
+
382
+ def build_sort_key(sort_by)
383
+ tokens = tokenize_column_list(sort_by)
384
+
385
+ tokens.collect do |token|
386
+ key = token.sub(DESCENDING_ORDER_PREFIX, '')
387
+ if token =~ DESCENDING_ORDER_PREFIX
388
+ descending_order_sort_key(key)
389
+ else
390
+ ascending_order_sort_key(key)
391
+ end
392
+ end
393
+ end
394
+
395
+ def descending_order_sort_key(key)
396
+ {
397
+ :key => key,
398
+ :order => "descending",
399
+ }
400
+ end
401
+
402
+ def ascending_order_sort_key(key)
403
+ {
404
+ :key => key,
405
+ :order => "ascending",
406
+ }
407
+ end
408
+
409
+ def default_sort_key #XX use #ascending_order_sort_key("_id")
410
+ [
411
+ {
412
+ :key => "_id",
413
+ :order => "ascending",
414
+ }
415
+ ]
416
+ end
417
+
418
+ def create_window_options(limit, offset)
419
+ window_options = {}
420
+ if limit
421
+ window_options[:limit] = limit
422
+ end
423
+ if offset
424
+ window_options[:offset] = offset
425
+ end
426
+ window_options
427
+ end
428
+
429
+ def access_column(table, column)
430
+ columns = column.split(".")
431
+ columns.each do |name|
432
+ table = table.column(name).range
433
+ end
434
+ table
435
+ end
436
+
437
+ def format_result(result, output_columns)
438
+ if result.empty?
439
+ return []
440
+ end
441
+
442
+ column_tokens = tokenize_column_list(output_columns)
443
+ column_list = build_column_list(result, column_tokens)
444
+
445
+ result.collect do |record|
446
+ format_record(column_list, record)
447
+ end
448
+ end
449
+
450
+ def format_record(column_list, record)
451
+ column_list.collect do |column, access_column|
452
+ value = record[column]
453
+ to_json(value, access_column)
454
+ end
455
+ end
456
+
457
+ def to_json(value, column)
458
+ case value
459
+ when ::Time
460
+ value.to_f
461
+ when nil
462
+ if column.name =~ /Int/
463
+ 0
464
+ else
465
+ ""
466
+ end
467
+ when Groonga::Record
468
+ value["_key"]
469
+ when Array
470
+ value.collect do |element|
471
+ to_json(element, value)
472
+ end
473
+ else
474
+ value
475
+ end
476
+ end
477
+
478
+ def column_included_in_record?(column, record)
479
+ if record.respond_to?(:have_column?)
480
+ record.have_column?(column)
481
+ else
482
+ record.include?(column)
483
+ end
484
+ end
485
+
486
+ def build_column_list(result, columns)
487
+ access_table = result.first.table
488
+
489
+ table = result.first.key
490
+ unless table.is_a?(Groonga::Table)
491
+ table = result.first.table
492
+ end
493
+ columns = columns.collect do |column|
494
+ if column == "*"
495
+ table.columns.collect(&:name).collect do |name|
496
+ name.sub(/\A[A-Za-z0-9_]+\./, '')
497
+ end
498
+ else
499
+ column if column_included_in_record?(column, result.first)
500
+ end
501
+ end.flatten.compact
502
+
503
+ columns.collect do |column|
504
+ [column, access_column(access_table, column)]
505
+ end
506
+ end
507
+ end
508
+
509
+ class Result
510
+ def ==(other) # XXX needs more strict/rigid check
511
+ results = [
512
+ hit_count == other.hit_count,
513
+ result_count == other.result_count,
514
+ formatted_result == other.formatted_result,
515
+ drilldown_results == other.drilldown_results,
516
+ ]
517
+
518
+ results.all?
519
+ end
520
+ end
521
+
522
+ class CommandResult < Result
523
+ def initialize(result)
524
+ @result = result
525
+ end
526
+
527
+ def hit_count
528
+ @result.n_hits
529
+ end
530
+
531
+ def result_count
532
+ @result.records.size
533
+ end
534
+
535
+ def formatted_result
536
+ @result.values
537
+ end
538
+
539
+ def drilldown_results
540
+ @result.drill_down.values.collect(&:values)
541
+ end
542
+ end
543
+
544
+ class MethodResult < Result
545
+ def initialize(result, sorted_result, formatted_result, drilldown_results)
546
+ @result = result
547
+ @sorted_result = sorted_result
548
+ @formatted_result = formatted_result
549
+ @drilldown_results = drilldown_results
550
+ end
551
+
552
+ def hit_count
553
+ @result.size
554
+ end
555
+
556
+ def result_count
557
+ sorted_result.size
558
+ end
559
+
560
+ def formatted_result
561
+ @formatted_result
562
+ end
563
+
564
+ def drilldown_results
565
+ if @drilldown_results.nil?
566
+ []
567
+ else
568
+ @drilldown_results.collect do |result|
569
+ result[:format]
570
+ end
571
+ end
572
+ end
573
+
574
+ private
575
+ def sorted_result
576
+ @sorted_result || @result
577
+ end
578
+ end
579
+
580
+ class BenchmarkResult
581
+ attr_accessor :result
582
+ attr_accessor :profile
583
+ attr_reader :benchmark_result
584
+
585
+ class Time < BenchmarkResult
586
+ def initialize(profile, target_object, query, &block)
587
+ @intercepted_method_times = {}
588
+ @profile = profile
589
+ @target_object = target_object
590
+ @query = query
591
+ each_intercepted_methods(@profile.intercepted_methods) do |klass, method_name, depth|
592
+ intercept_method(klass, method_name, depth)
593
+ end
594
+
595
+ measure_time(&block)
596
+
597
+ each_intercepted_methods(@profile.intercepted_methods) do |klass, method_name, depth|
598
+ reset_intercepted_method(klass, method_name, depth)
599
+ end
600
+ end
601
+
602
+ def lines
603
+ super + intercepted_method_lines
604
+ end
605
+
606
+ def padding(depth)
607
+ " " * (depth + 1)
608
+ end
609
+
610
+ def intercepted_method_lines
611
+ lines = []
612
+ @intercepted_method_times.each do |method_name, status|
613
+ depth = status[:depth]
614
+ count = status[:benchmark_results].size
615
+ results = status[:benchmark_results]
616
+
617
+ if count == 1
618
+ result = results.first
619
+ lines << single_line(method_name, result, depth)
620
+ elsif count == 0
621
+ # do nothing
622
+ else
623
+ total = results.inject do |result, _total|
624
+ result + _total
625
+ end
626
+
627
+ total_result = ["#{padding(depth)}#{method_name}", total]
628
+ lines << total_result
629
+
630
+ lines += multile_lines(method_name, results, depth + 1)
631
+ end
632
+ end
633
+
634
+ lines
635
+ end
636
+
637
+ def single_line(method_name, result, depth)
638
+
639
+ ["#{padding(depth)}#{method_name}", result]
640
+ end
641
+
642
+ def multile_lines(method_name, results, depth)
643
+ index = 0
644
+
645
+ results.collect do |result|
646
+ index += 1
647
+ if @profile.respond_to?(:guess_invocation_label)
648
+ label = @profile.guess_invocation_label(@query, method_name, index)
649
+ end
650
+ label ||= index
651
+
652
+ ["#{padding(depth)}#{label}", result]
653
+ end
654
+ end
655
+
656
+ def +(other)
657
+ intercepted_method_times = other.instance_variable_get(:@intercepted_method_times)
658
+ intercepted_method_times.each do |method_name, time|
659
+ time[:benchmark_results].each_with_index do |result, index|
660
+ @intercepted_method_times[method_name][:benchmark_results][index] += result
661
+ end
662
+ end
663
+ super(other)
664
+ end
665
+
666
+ private
667
+ def measure_time
668
+ @benchmark_result = Benchmark.measure do
669
+ @result = yield
670
+ end
671
+ end
672
+
673
+ def each_intercepted_methods(intercepted_methods, depth=0, &block)
674
+ intercepted_methods.each do |method|
675
+ case method
676
+ when Symbol
677
+ yield(@target_object.class, method, depth)
678
+ when Method
679
+ if method.receiver.is_a?(Class)
680
+ yield(method.owner, method.name, depth)
681
+ else
682
+ yield(method.receiver.class, method.name, depth)
683
+ end
684
+ when Array
685
+ each_intercepted_methods(method, depth + 1, &block)
686
+ else
687
+ raise "bad"
688
+ end
689
+ end
690
+ end
691
+
692
+ def intercept_method(klass, method_name, depth)
693
+ intercepted_method_times = @intercepted_method_times
694
+ original_method_name = original_method_name(method_name)
695
+
696
+ intercepted_method_times[method_name] = {}
697
+ intercepted_method_times[method_name][:benchmark_results] = []
698
+ intercepted_method_times[method_name][:depth] = depth
699
+
700
+ klass.class_exec do
701
+ alias_method original_method_name, method_name
702
+ define_method method_name do |*arguments, &block|
703
+ returned_object = nil
704
+ benchmark_result = Benchmark.measure do
705
+ returned_object = __send__(original_method_name, *arguments, &block)
706
+ end
707
+ intercepted_method_times[method_name][:benchmark_results] << benchmark_result
708
+ returned_object
709
+ end
710
+ end
711
+ end
712
+
713
+ def reset_intercepted_method(klass, method_name, depth)
714
+ original_method_name = original_method_name(method_name)
715
+
716
+ klass.class_exec do
717
+ alias_method method_name, original_method_name
718
+ end
719
+ end
720
+
721
+ def original_method_name(method_name)
722
+ :"__intercepted__#{method_name}"
723
+ end
724
+ end
725
+
726
+ def lines
727
+ [["#{name} (#{result.hit_count} hits)", @benchmark_result]]
728
+ end
729
+
730
+ def name
731
+ profile.name
732
+ end
733
+
734
+ def +(other)
735
+ @benchmark_result += other.benchmark_result
736
+ self
737
+ end
738
+ end
739
+
740
+ class Profile
741
+ include ColumnTokenizer
742
+
743
+ attr_accessor :mode
744
+ attr_reader :name, :intercepted_methods
745
+ def initialize(name, selector, intercepted_methods=[])
746
+ @name = name
747
+ @selector = selector
748
+ @intercepted_methods = intercepted_methods
749
+ end
750
+
751
+ def take_benchmark(query)
752
+ if mode == :measure_time
753
+ measure_time(query)
754
+ else
755
+ raise "bad"
756
+ end
757
+ end
758
+
759
+ def guess_invocation_label(query, method_name, index)
760
+ if method_name.to_s =~ /drilldown|do_group/
761
+ columns = tokenize_column_list(query.drilldown_columns).uniq
762
+ columns[index - 1]
763
+ else
764
+ raise "bad: #{method_name}"
765
+ end
766
+ end
767
+
768
+ private
769
+ def measure_time(query)
770
+ BenchmarkResult::Time.new(self, @selector, query) do
771
+ result = @selector.select(query)
772
+ result
773
+ end
774
+ end
775
+ end
776
+
777
+ class BenchmarkRunner
778
+ attr_accessor :context
779
+ DEFAULT_MODE = :measure_time # :mesure_memory, :mesure_io, :mesure_???
780
+
781
+ def initialize(options={})
782
+ @options = options
783
+ @profiles = []
784
+ @queries = []
785
+ end
786
+
787
+ def benchmark_mode
788
+ @options[:mode] || DEFAULT_MODE
789
+ end
790
+
791
+ def add_profile(profile)
792
+ profile.mode = benchmark_mode
793
+ @profiles << profile
794
+ end
795
+
796
+ def add_query(query, label=nil)
797
+ @queries << [query, label]
798
+ end
799
+
800
+ LOCK_TIMEOUT_SECONDS = 10
801
+ def lock
802
+ @context.database.lock(:timeout => LOCK_TIMEOUT_SECONDS * 1000) do
803
+ yield
804
+ end
805
+ end
806
+
807
+ def collect_benchmarks(query)
808
+ lock do
809
+ @profiles.collect do |profile|
810
+ profile.take_benchmark(query)
811
+ end
812
+ end
813
+ end
814
+
815
+ def debug_benchmarks(query, benchmarks)
816
+ if ENV["DEBUG"]
817
+ pp query
818
+ pp benchmarks
819
+ end
820
+ end
821
+
822
+ def run_once(query)
823
+ benchmarks = do_run_once(query)
824
+ report_benchmarks(benchmarks, query)
825
+ end
826
+
827
+ def do_run_once(query)
828
+ benchmarks = collect_benchmarks(query)
829
+
830
+ debug_benchmarks(query, benchmarks)
831
+ verify_results(benchmarks)
832
+
833
+ benchmarks
834
+ end
835
+
836
+ def report_benchmarks(benchmarks, query, label)
837
+ report = create_report(benchmarks, query, label)
838
+ report.print
839
+ end
840
+
841
+ DEFAULT_REPEAT_COUNT = 5
842
+ def repeat_count
843
+ @options[:repeat_count] || DEFAULT_REPEAT_COUNT
844
+ end
845
+
846
+ def run(query=nil)
847
+ if query
848
+ do_run(query)
849
+ else
850
+ raise "no query" if @queries.empty?
851
+
852
+ index = 0
853
+ @queries.each do |query, label|
854
+ index += 1
855
+ do_run(query, "#{index}. #{label}")
856
+ puts
857
+ puts
858
+ end
859
+ end
860
+ end
861
+
862
+ def do_run(query, label=nil)
863
+ benchmarks_set = repeat_count.times.collect do
864
+ do_run_once(query)
865
+ end
866
+ total_benchmarks = benchmarks_set.shift
867
+ benchmarks_set.each do |benchmarks|
868
+ benchmarks.each_with_index do |benchmark, index|
869
+ total_benchmarks[index] += benchmark
870
+ end
871
+ end
872
+ report_benchmarks(total_benchmarks, query, label)
873
+ end
874
+
875
+ def verify_results(benchmarks)
876
+ return if ENV["NO_VERIFY"]
877
+ benchmarks = benchmarks.dup
878
+
879
+ expected_result = benchmarks.shift.result
880
+ benchmarks.each do |benchmark|
881
+ raise "bad" unless assert_equivalent_to(expected_result, benchmark.result)
882
+ end
883
+ end
884
+
885
+ def assert_equivalent_to(first_result, second_result)
886
+ first_result == second_result
887
+ end
888
+
889
+ def create_report(benchmarks, query, label=nil)
890
+ Report.new(query, label, benchmarks, repeat_count)
891
+ end
892
+
893
+ DEFAULT_WIKIPEDIA_DATABASE_LOCATION = "/tmp/wikipedia-db/db"
894
+ class << self
895
+ def select_benchmark_default_setup(runner, options=nil)
896
+ options ||= {}
897
+
898
+ configuration = Configuration.new
899
+ configuration.database_path = options[:database_path] || DEFAULT_WIKIPEDIA_DATABASE_LOCATION
900
+ ensure_database(configuration)
901
+
902
+ context = Groonga::Context.new
903
+ select_command = SelectorByCommand.new(context, configuration.database_path)
904
+ select_method = SelectorByMethod.new(context, configuration.database_path)
905
+ select_command_profile = command_selector_profile(select_command)
906
+ select_method_profile = method_selector_profile(select_method)
907
+
908
+ runner.context = context
909
+ runner.add_profile(select_command_profile)
910
+ runner.add_profile(select_method_profile)
911
+ end
912
+
913
+ def ensure_database(configuration)
914
+ unless File.exist?(configuration.database_path)
915
+ puts 'you must create wikipedia database to use, or specify it via "DATABASE_PATH" environment variable'
916
+ puts
917
+ puts 'how to create wikipedia database'
918
+ puts '1. download wikipedia dump.'
919
+ puts ' $ wget -c http://download.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2'
920
+ puts '2. create groonga database from the dump'
921
+ puts ' $ cat jawiki-latest-pages-articles.xml.bz2 | bunzip2 | ruby1.9.1 ./benchmark/create-wikipedia-database.rb'
922
+ exit 1
923
+ end
924
+ end
925
+
926
+ def command_selector_profile(select_command)
927
+ Profile.new("select by command",
928
+ select_command,
929
+ [select_command.context.method(:send),
930
+ Groonga::Context::SelectResult.method(:parse)])
931
+ end
932
+
933
+ def method_selector_profile(select_method)
934
+ Profile.new("select by method",
935
+ select_method,
936
+ [:do_select,
937
+ :sort,
938
+ :format,
939
+ :drilldown, [:do_group,
940
+ :drilldown_sort,
941
+ :drilldown_format]])
942
+ end
943
+
944
+ def output_columns_without_content
945
+ "--output_columns '_id _key year wday timestamp month hour date last_contributor'"
946
+ end
947
+
948
+ def output_columns_with_content
949
+ "--output_columns '_id _key year wday timestamp month hour date last_contributor content'"
950
+ end
951
+
952
+ def predefined_queries
953
+ [
954
+ ["select Documents",
955
+ "minimum command"],
956
+ ["select Documents --filter true",
957
+ "select all"],
958
+ ["select Documents --filter false",
959
+ "select none"],
960
+ ["select Documents content アルミ #{output_columns_without_content}",
961
+ "full text search"],
962
+ ["select Documents content アルミ #{output_columns_without_content} --limit 0",
963
+ "full text search with no limit"],
964
+ ["select Documents content アルミ #{output_columns_with_content}",
965
+ "full text search output long text column"],
966
+ ["select Documents content アルミ #{output_columns_without_content} --limit 1000",
967
+ "full text search with large limit"],
968
+ ["select Documents --filter true --limit 0 --drilldown last_contributor --drilldown_sortby _nsubrecs",
969
+ "drilldown"],
970
+ ["select Documents --filter true --limit 0 --drilldown last_contributor --drilldown_sortby _nsubrecs --drilldown_limit 10000",
971
+ "drilldown with large drilldown_limit"],
972
+ ["select Documents --sortby _key",
973
+ "sort"],
974
+ ["select Documents --sortby _key --drilldown 'year month date wday hour, last_contributor links' --drilldown_sortby _nsubrecs",
975
+ "sort with drilldown"],
976
+ ]
977
+ end
978
+
979
+ def load_predefined_queries(runner, options)
980
+ predefined_queries.each do |command, label|
981
+ query = Query.parse_groonga_query_log(command)
982
+ runner.add_query(query, label)
983
+ end
984
+ end
985
+ end
986
+ end
987
+
988
+ class Report
989
+ def initialize(query, query_label, benchmarks, repeat_count)
990
+ @query = query
991
+ @query_label = query_label
992
+ @benchmarks = benchmarks
993
+ @repeat_count = repeat_count
994
+ end
995
+
996
+ def compare
997
+ end
998
+
999
+ def print
1000
+ puts "select command: #{@query_label}"
1001
+ puts " #{@query.original_log_entry}"
1002
+ puts
1003
+ puts "repeated #{@repeat_count} time(s). Average times are:"
1004
+
1005
+ lines = []
1006
+ @benchmarks.each do |benchmark|
1007
+ lines += benchmark.lines
1008
+ end
1009
+ width = lines.collect(&:first).collect(&:size).max
1010
+
1011
+ puts(" " * (width - 1) + Benchmark::Tms::CAPTION.rstrip)
1012
+ lines.each do |label, result|
1013
+ puts "#{label.ljust(width)} #{(result / @repeat_count).to_s.strip}"
1014
+ end
1015
+ end
1016
+ end
1017
+
1018
+ options = {
1019
+ :method => [:measure_time],
1020
+ }
1021
+
1022
+ OptionParser.new do |parser|
1023
+ parser.on("--repeat=COUNT",
1024
+ "repeat each query COUNT times",
1025
+ "(default: #{BenchmarkRunner::DEFAULT_REPEAT_COUNT})") do |count|
1026
+ options[:repeat_count] = count.to_i
1027
+ end
1028
+
1029
+ parser.on("--command=COMMAND",
1030
+ "use COMMAND instead of default predefined ones") do |command|
1031
+ options[:query] = Query.parse_groonga_query_log(command)
1032
+ end
1033
+
1034
+ parser.on("--database=PATH",
1035
+ "use database located at PATH",
1036
+ "(default: #{BenchmarkRunner::DEFAULT_WIKIPEDIA_DATABASE_LOCATION})") do |command|
1037
+ options[:database_path] = command
1038
+ end
1039
+ end.parse!(ARGV)
1040
+
1041
+ runner = BenchmarkRunner.new(options).tap do |runner|
1042
+ BenchmarkRunner.select_benchmark_default_setup(runner, options)
1043
+ if options[:query].nil?
1044
+ BenchmarkRunner.load_predefined_queries(runner, options)
1045
+ end
1046
+ end
1047
+
1048
+ if options[:query]
1049
+ runner.run(options[:query])
1050
+ else
1051
+ runner.run
1052
+ end