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

Sign up to get free protection for your applications and to get access to all the features.
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