droonga-engine 1.0.1

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 (341) hide show
  1. data/.dir-locals.el +3 -0
  2. data/.gitignore +6 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +7 -0
  5. data/Gemfile +66 -0
  6. data/LICENSE.txt +14 -0
  7. data/README.md +17 -0
  8. data/Rakefile +64 -0
  9. data/benchmark/benchmark.rb +123 -0
  10. data/benchmark/utils.rb +246 -0
  11. data/benchmark/watch/benchmark-notify.rb +143 -0
  12. data/benchmark/watch/benchmark-notify.sh +20 -0
  13. data/benchmark/watch/benchmark-publish.rb +120 -0
  14. data/benchmark/watch/benchmark-scan.rb +213 -0
  15. data/bin/droonga-catalog-generate +103 -0
  16. data/bin/droonga-engine +20 -0
  17. data/bin/droonga-engine-service +20 -0
  18. data/doc/text/news.md +106 -0
  19. data/droonga-engine.gemspec +52 -0
  20. data/lib/droonga/adapter.rb +48 -0
  21. data/lib/droonga/adapter_runner.rb +104 -0
  22. data/lib/droonga/catalog/base.rb +41 -0
  23. data/lib/droonga/catalog/collection_volume.rb +106 -0
  24. data/lib/droonga/catalog/dataset.rb +69 -0
  25. data/lib/droonga/catalog/errors.rb +113 -0
  26. data/lib/droonga/catalog/schema.rb +186 -0
  27. data/lib/droonga/catalog/single_volume.rb +28 -0
  28. data/lib/droonga/catalog/slice.rb +41 -0
  29. data/lib/droonga/catalog/version1.rb +427 -0
  30. data/lib/droonga/catalog/version2.rb +96 -0
  31. data/lib/droonga/catalog/version2_validator.rb +63 -0
  32. data/lib/droonga/catalog/volume.rb +33 -0
  33. data/lib/droonga/catalog/volume_collection.rb +56 -0
  34. data/lib/droonga/catalog_generator.rb +156 -0
  35. data/lib/droonga/catalog_loader.rb +56 -0
  36. data/lib/droonga/catalog_observer.rb +83 -0
  37. data/lib/droonga/collector.rb +38 -0
  38. data/lib/droonga/collector_message.rb +71 -0
  39. data/lib/droonga/collector_runner.rb +64 -0
  40. data/lib/droonga/collectors/and.rb +26 -0
  41. data/lib/droonga/collectors/or.rb +26 -0
  42. data/lib/droonga/collectors/sum.rb +26 -0
  43. data/lib/droonga/collectors.rb +18 -0
  44. data/lib/droonga/dispatcher.rb +326 -0
  45. data/lib/droonga/distributed_command_planner.rb +179 -0
  46. data/lib/droonga/distributor.rb +87 -0
  47. data/lib/droonga/engine/command/droonga_engine.rb +441 -0
  48. data/lib/droonga/engine/version.rb +20 -0
  49. data/lib/droonga/engine.rb +80 -0
  50. data/lib/droonga/engine_state.rb +79 -0
  51. data/lib/droonga/error.rb +73 -0
  52. data/lib/droonga/error_messages.rb +33 -0
  53. data/lib/droonga/event_loop.rb +46 -0
  54. data/lib/droonga/farm.rb +58 -0
  55. data/lib/droonga/fluent_message_receiver.rb +191 -0
  56. data/lib/droonga/fluent_message_sender.rb +140 -0
  57. data/lib/droonga/forwarder.rb +119 -0
  58. data/lib/droonga/handler.rb +49 -0
  59. data/lib/droonga/handler_message.rb +61 -0
  60. data/lib/droonga/handler_messenger.rb +119 -0
  61. data/lib/droonga/handler_runner.rb +125 -0
  62. data/lib/droonga/input_message.rb +51 -0
  63. data/lib/droonga/job_protocol.rb +20 -0
  64. data/lib/droonga/job_pusher.rb +179 -0
  65. data/lib/droonga/job_receiver.rb +70 -0
  66. data/lib/droonga/loggable.rb +29 -0
  67. data/lib/droonga/logger.rb +142 -0
  68. data/lib/droonga/message_matcher.rb +109 -0
  69. data/lib/droonga/output_message.rb +55 -0
  70. data/lib/droonga/planner.rb +47 -0
  71. data/lib/droonga/pluggable.rb +31 -0
  72. data/lib/droonga/plugin/metadata/adapter_input_message.rb +39 -0
  73. data/lib/droonga/plugin/metadata/adapter_output_message.rb +39 -0
  74. data/lib/droonga/plugin/metadata/collector_message.rb +39 -0
  75. data/lib/droonga/plugin/metadata/handler_action.rb +39 -0
  76. data/lib/droonga/plugin/metadata/input_message.rb +54 -0
  77. data/lib/droonga/plugin.rb +43 -0
  78. data/lib/droonga/plugin_loader.rb +63 -0
  79. data/lib/droonga/plugin_registry.rb +66 -0
  80. data/lib/droonga/plugins/basic.rb +54 -0
  81. data/lib/droonga/plugins/crud.rb +145 -0
  82. data/lib/droonga/plugins/dump.rb +97 -0
  83. data/lib/droonga/plugins/error.rb +51 -0
  84. data/lib/droonga/plugins/groonga/column_create.rb +123 -0
  85. data/lib/droonga/plugins/groonga/column_list.rb +124 -0
  86. data/lib/droonga/plugins/groonga/column_remove.rb +65 -0
  87. data/lib/droonga/plugins/groonga/column_rename.rb +67 -0
  88. data/lib/droonga/plugins/groonga/delete.rb +117 -0
  89. data/lib/droonga/plugins/groonga/generic_command.rb +105 -0
  90. data/lib/droonga/plugins/groonga/generic_response.rb +43 -0
  91. data/lib/droonga/plugins/groonga/select.rb +236 -0
  92. data/lib/droonga/plugins/groonga/table_create.rb +111 -0
  93. data/lib/droonga/plugins/groonga/table_list.rb +120 -0
  94. data/lib/droonga/plugins/groonga/table_remove.rb +57 -0
  95. data/lib/droonga/plugins/groonga.rb +37 -0
  96. data/lib/droonga/plugins/search/distributed_search_planner.rb +407 -0
  97. data/lib/droonga/plugins/search.rb +146 -0
  98. data/lib/droonga/plugins/watch.rb +178 -0
  99. data/lib/droonga/processor.rb +63 -0
  100. data/lib/droonga/reducer.rb +169 -0
  101. data/lib/droonga/replier.rb +49 -0
  102. data/lib/droonga/schema_applier.rb +167 -0
  103. data/lib/droonga/searcher/mecab_filter.rb +67 -0
  104. data/lib/droonga/searcher.rb +733 -0
  105. data/lib/droonga/server.rb +45 -0
  106. data/lib/droonga/session.rb +99 -0
  107. data/lib/droonga/single_step.rb +68 -0
  108. data/lib/droonga/single_step_definition.rb +54 -0
  109. data/lib/droonga/slice.rb +122 -0
  110. data/lib/droonga/status_code.rb +25 -0
  111. data/lib/droonga/step_runner.rb +64 -0
  112. data/lib/droonga/sweeper.rb +42 -0
  113. data/lib/droonga/test/stub_handler.rb +37 -0
  114. data/lib/droonga/test/stub_handler_message.rb +35 -0
  115. data/lib/droonga/test/stub_handler_messenger.rb +34 -0
  116. data/lib/droonga/test/stub_planner.rb +31 -0
  117. data/lib/droonga/test.rb +21 -0
  118. data/lib/droonga/watch_schema.rb +92 -0
  119. data/lib/droonga/watcher.rb +257 -0
  120. data/lib/droonga/worker.rb +61 -0
  121. data/sample/cluster/catalog.json +42 -0
  122. data/sample/mecab_filter/data.grn +7 -0
  123. data/sample/mecab_filter/ddl.grn +7 -0
  124. data/sample/mecab_filter/search_with_mecab_filter.json +21 -0
  125. data/sample/mecab_filter/search_without_mecab_filter.json +21 -0
  126. data/test/command/config/default/catalog.json +85 -0
  127. data/test/command/config/default/fluentd.conf +11 -0
  128. data/test/command/config/version1/catalog.json +68 -0
  129. data/test/command/config/version1/fluentd.conf +11 -0
  130. data/test/command/fixture/documents.jsons +208 -0
  131. data/test/command/fixture/event.jsons +41 -0
  132. data/test/command/fixture/user-table-array.jsons +38 -0
  133. data/test/command/fixture/user-table.jsons +47 -0
  134. data/test/command/run-test.rb +34 -0
  135. data/test/command/suite/add/dimension/column.catalog.json +28 -0
  136. data/test/command/suite/add/dimension/column.expected +41 -0
  137. data/test/command/suite/add/dimension/column.test +51 -0
  138. data/test/command/suite/add/dimension/integer.catalog.json +19 -0
  139. data/test/command/suite/add/dimension/integer.expected +41 -0
  140. data/test/command/suite/add/dimension/integer.test +51 -0
  141. data/test/command/suite/add/error/invalid-integer.expected +46 -0
  142. data/test/command/suite/add/error/invalid-integer.test +12 -0
  143. data/test/command/suite/add/error/invalid-time.expected +46 -0
  144. data/test/command/suite/add/error/invalid-time.test +12 -0
  145. data/test/command/suite/add/error/missing-key.expected +25 -0
  146. data/test/command/suite/add/error/missing-key.test +16 -0
  147. data/test/command/suite/add/error/missing-table.expected +25 -0
  148. data/test/command/suite/add/error/missing-table.test +16 -0
  149. data/test/command/suite/add/error/unknown-column.expected +46 -0
  150. data/test/command/suite/add/error/unknown-column.test +12 -0
  151. data/test/command/suite/add/error/unknown-table.expected +25 -0
  152. data/test/command/suite/add/error/unknown-table.test +17 -0
  153. data/test/command/suite/add/minimum.expected +6 -0
  154. data/test/command/suite/add/minimum.test +11 -0
  155. data/test/command/suite/add/with-values.expected +6 -0
  156. data/test/command/suite/add/with-values.test +17 -0
  157. data/test/command/suite/add/without-key.expected +6 -0
  158. data/test/command/suite/add/without-key.test +16 -0
  159. data/test/command/suite/groonga/column_create/scalar.expected +26 -0
  160. data/test/command/suite/groonga/column_create/scalar.test +17 -0
  161. data/test/command/suite/groonga/column_create/unknown-table.expected +14 -0
  162. data/test/command/suite/groonga/column_create/unknown-table.test +7 -0
  163. data/test/command/suite/groonga/column_create/vector.expected +26 -0
  164. data/test/command/suite/groonga/column_create/vector.test +18 -0
  165. data/test/command/suite/groonga/column_list/success.expected +86 -0
  166. data/test/command/suite/groonga/column_list/success.test +24 -0
  167. data/test/command/suite/groonga/column_list/unknown-table.expected +13 -0
  168. data/test/command/suite/groonga/column_list/unknown-table.test +7 -0
  169. data/test/command/suite/groonga/column_remove/success.expected +39 -0
  170. data/test/command/suite/groonga/column_remove/success.test +25 -0
  171. data/test/command/suite/groonga/column_remove/unknown-column.expected +27 -0
  172. data/test/command/suite/groonga/column_remove/unknown-column.test +16 -0
  173. data/test/command/suite/groonga/column_remove/unknown-table.expected +14 -0
  174. data/test/command/suite/groonga/column_remove/unknown-table.test +7 -0
  175. data/test/command/suite/groonga/column_rename/success.expected +39 -0
  176. data/test/command/suite/groonga/column_rename/success.test +26 -0
  177. data/test/command/suite/groonga/column_rename/unknown-column.expected +27 -0
  178. data/test/command/suite/groonga/column_rename/unknown-column.test +16 -0
  179. data/test/command/suite/groonga/column_rename/unknown-table.expected +14 -0
  180. data/test/command/suite/groonga/column_rename/unknown-table.test +7 -0
  181. data/test/command/suite/groonga/delete/duplicated-identifiers.expected +27 -0
  182. data/test/command/suite/groonga/delete/duplicated-identifiers.test +17 -0
  183. data/test/command/suite/groonga/delete/filter.expected +19 -0
  184. data/test/command/suite/groonga/delete/filter.test +19 -0
  185. data/test/command/suite/groonga/delete/invalid-filter.expected +14 -0
  186. data/test/command/suite/groonga/delete/invalid-filter.test +9 -0
  187. data/test/command/suite/groonga/delete/no-identifier.expected +27 -0
  188. data/test/command/suite/groonga/delete/no-identifier.test +15 -0
  189. data/test/command/suite/groonga/delete/success.expected +19 -0
  190. data/test/command/suite/groonga/delete/success.test +19 -0
  191. data/test/command/suite/groonga/delete/unknown-table.expected +14 -0
  192. data/test/command/suite/groonga/delete/unknown-table.test +7 -0
  193. data/test/command/suite/groonga/select/minimum.expected +22 -0
  194. data/test/command/suite/groonga/select/minimum.test +8 -0
  195. data/test/command/suite/groonga/table_create/array.expected +14 -0
  196. data/test/command/suite/groonga/table_create/array.test +8 -0
  197. data/test/command/suite/groonga/table_create/hash.expected +13 -0
  198. data/test/command/suite/groonga/table_create/hash.test +8 -0
  199. data/test/command/suite/groonga/table_list/success.expected +71 -0
  200. data/test/command/suite/groonga/table_list/success.test +15 -0
  201. data/test/command/suite/groonga/table_remove/success.expected +13 -0
  202. data/test/command/suite/groonga/table_remove/success.test +8 -0
  203. data/test/command/suite/groonga/table_remove/unknown-table.expected +14 -0
  204. data/test/command/suite/groonga/table_remove/unknown-table.test +7 -0
  205. data/test/command/suite/message/error/missing-dataset.expected +9 -0
  206. data/test/command/suite/message/error/missing-dataset.test +5 -0
  207. data/test/command/suite/message/error/unknown-dataset.expected +9 -0
  208. data/test/command/suite/message/error/unknown-dataset.test +6 -0
  209. data/test/command/suite/message/error/unknown-type.expected +9 -0
  210. data/test/command/suite/message/error/unknown-type.test +6 -0
  211. data/test/command/suite/search/adjusters/multiple.catalog.json +38 -0
  212. data/test/command/suite/search/adjusters/multiple.expected +19 -0
  213. data/test/command/suite/search/adjusters/multiple.test +75 -0
  214. data/test/command/suite/search/adjusters/one.catalog.json +38 -0
  215. data/test/command/suite/search/adjusters/one.expected +19 -0
  216. data/test/command/suite/search/adjusters/one.test +66 -0
  217. data/test/command/suite/search/attributes/array.expected +21 -0
  218. data/test/command/suite/search/attributes/array.test +28 -0
  219. data/test/command/suite/search/attributes/hash.expected +30 -0
  220. data/test/command/suite/search/attributes/hash.test +36 -0
  221. data/test/command/suite/search/complex.expected +48 -0
  222. data/test/command/suite/search/complex.test +23 -0
  223. data/test/command/suite/search/condition/nested.expected +15 -0
  224. data/test/command/suite/search/condition/nested.test +27 -0
  225. data/test/command/suite/search/condition/query/nonexistent_column.catalog.json +37 -0
  226. data/test/command/suite/search/condition/query/nonexistent_column.expected +48 -0
  227. data/test/command/suite/search/condition/query/nonexistent_column.test +33 -0
  228. data/test/command/suite/search/condition/query/syntax_error.catalog.json +36 -0
  229. data/test/command/suite/search/condition/query/syntax_error.expected +48 -0
  230. data/test/command/suite/search/condition/query/syntax_error.test +33 -0
  231. data/test/command/suite/search/condition/query.expected +24 -0
  232. data/test/command/suite/search/condition/query.test +23 -0
  233. data/test/command/suite/search/condition/script.expected +24 -0
  234. data/test/command/suite/search/condition/script.test +26 -0
  235. data/test/command/suite/search/error/cyclic-source.expected +14 -0
  236. data/test/command/suite/search/error/cyclic-source.test +12 -0
  237. data/test/command/suite/search/error/deeply-cyclic-source.expected +17 -0
  238. data/test/command/suite/search/error/deeply-cyclic-source.test +15 -0
  239. data/test/command/suite/search/error/missing-source-parameter.expected +13 -0
  240. data/test/command/suite/search/error/missing-source-parameter.test +11 -0
  241. data/test/command/suite/search/error/no-query.expected +9 -0
  242. data/test/command/suite/search/error/no-query.test +7 -0
  243. data/test/command/suite/search/error/unknown-source.expected +52 -0
  244. data/test/command/suite/search/error/unknown-source.test +12 -0
  245. data/test/command/suite/search/group/count.expected +10 -0
  246. data/test/command/suite/search/group/count.test +18 -0
  247. data/test/command/suite/search/group/limit.expected +15 -0
  248. data/test/command/suite/search/group/limit.test +20 -0
  249. data/test/command/suite/search/group/string.expected +32 -0
  250. data/test/command/suite/search/group/string.test +40 -0
  251. data/test/command/suite/search/group/subrecord/with-sort.catalog.json +33 -0
  252. data/test/command/suite/search/group/subrecord/with-sort.expected +30 -0
  253. data/test/command/suite/search/group/subrecord/with-sort.test +81 -0
  254. data/test/command/suite/search/multiple/chained.expected +41 -0
  255. data/test/command/suite/search/multiple/chained.test +39 -0
  256. data/test/command/suite/search/multiple/parallel.expected +35 -0
  257. data/test/command/suite/search/multiple/parallel.test +35 -0
  258. data/test/command/suite/search/output/attributes/invalid.catalog.json +13 -0
  259. data/test/command/suite/search/output/attributes/invalid.expected +44 -0
  260. data/test/command/suite/search/output/attributes/invalid.test +28 -0
  261. data/test/command/suite/search/range/only-output.expected +24 -0
  262. data/test/command/suite/search/range/only-output.test +23 -0
  263. data/test/command/suite/search/range/only-sort.expected +24 -0
  264. data/test/command/suite/search/range/only-sort.test +26 -0
  265. data/test/command/suite/search/range/sort-and-output.expected +21 -0
  266. data/test/command/suite/search/range/sort-and-output.test +27 -0
  267. data/test/command/suite/search/range/too-large-output-offset.expected +12 -0
  268. data/test/command/suite/search/range/too-large-output-offset.test +23 -0
  269. data/test/command/suite/search/range/too-large-sort-offset.expected +12 -0
  270. data/test/command/suite/search/range/too-large-sort-offset.test +26 -0
  271. data/test/command/suite/search/response/elapsed_time.catalog.json +13 -0
  272. data/test/command/suite/search/response/elapsed_time.expected +11 -0
  273. data/test/command/suite/search/response/elapsed_time.test +26 -0
  274. data/test/command/suite/search/response/records/value/time.expected +20 -0
  275. data/test/command/suite/search/response/records/value/time.test +22 -0
  276. data/test/command/suite/search/simple.expected +48 -0
  277. data/test/command/suite/search/simple.test +22 -0
  278. data/test/command/suite/search/sort/default-offset-limit.expected +39 -0
  279. data/test/command/suite/search/sort/default-offset-limit.test +24 -0
  280. data/test/command/suite/search/sort/invisible-column.expected +24 -0
  281. data/test/command/suite/search/sort/invisible-column.test +26 -0
  282. data/test/command/suite/watch/subscribe.expected +6 -0
  283. data/test/command/suite/watch/subscribe.test +9 -0
  284. data/test/command/suite/watch/unsubscribe.expected +6 -0
  285. data/test/command/suite/watch/unsubscribe.test +9 -0
  286. data/test/performance/run-test.rb +56 -0
  287. data/test/performance/watch/catalog.json +33 -0
  288. data/test/performance/watch/feed.json +9 -0
  289. data/test/performance/watch/fluentd.conf +11 -0
  290. data/test/performance/watch/subscribe.json +3 -0
  291. data/test/unit/catalog/test_collection_volume.rb +103 -0
  292. data/test/unit/catalog/test_dataset.rb +104 -0
  293. data/test/unit/catalog/test_schema.rb +226 -0
  294. data/test/unit/catalog/test_single_volume.rb +31 -0
  295. data/test/unit/catalog/test_slice.rb +92 -0
  296. data/test/unit/catalog/test_version1.rb +361 -0
  297. data/test/unit/catalog/test_version2.rb +124 -0
  298. data/test/unit/catalog/test_version2_validator.rb +66 -0
  299. data/test/unit/catalog/test_volume_collection.rb +50 -0
  300. data/test/unit/fixtures/array.grn +18 -0
  301. data/test/unit/fixtures/catalog/version1.json +40 -0
  302. data/test/unit/fixtures/catalog/version2.json +62 -0
  303. data/test/unit/fixtures/document.grn +34 -0
  304. data/test/unit/fixtures/reference/array.grn +11 -0
  305. data/test/unit/fixtures/reference/hash.grn +7 -0
  306. data/test/unit/helper/distributed_search_planner_helper.rb +83 -0
  307. data/test/unit/helper/fixture.rb +28 -0
  308. data/test/unit/helper/plugin_helper.rb +38 -0
  309. data/test/unit/helper/sandbox.rb +86 -0
  310. data/test/unit/helper/stub_worker.rb +27 -0
  311. data/test/unit/helper/watch_helper.rb +23 -0
  312. data/test/unit/helper.rb +28 -0
  313. data/test/unit/plugins/crud/test_add.rb +190 -0
  314. data/test/unit/plugins/groonga/select/test_adapter_input.rb +510 -0
  315. data/test/unit/plugins/groonga/select/test_adapter_output.rb +201 -0
  316. data/test/unit/plugins/groonga/test_column_create.rb +171 -0
  317. data/test/unit/plugins/groonga/test_column_list.rb +170 -0
  318. data/test/unit/plugins/groonga/test_column_remove.rb +98 -0
  319. data/test/unit/plugins/groonga/test_column_rename.rb +105 -0
  320. data/test/unit/plugins/groonga/test_delete.rb +127 -0
  321. data/test/unit/plugins/groonga/test_table_create.rb +147 -0
  322. data/test/unit/plugins/groonga/test_table_list.rb +184 -0
  323. data/test/unit/plugins/groonga/test_table_remove.rb +61 -0
  324. data/test/unit/plugins/search/planner/test_basic.rb +120 -0
  325. data/test/unit/plugins/search/planner/test_group_by.rb +573 -0
  326. data/test/unit/plugins/search/planner/test_output.rb +388 -0
  327. data/test/unit/plugins/search/planner/test_sort_by.rb +938 -0
  328. data/test/unit/plugins/search/test_collector.rb +806 -0
  329. data/test/unit/plugins/search/test_handler.rb +930 -0
  330. data/test/unit/plugins/search/test_planner.rb +174 -0
  331. data/test/unit/plugins/test_basic.rb +510 -0
  332. data/test/unit/plugins/test_groonga.rb +70 -0
  333. data/test/unit/plugins/test_watch.rb +211 -0
  334. data/test/unit/run-test.rb +56 -0
  335. data/test/unit/test_catalog_generator.rb +93 -0
  336. data/test/unit/test_message_matcher.rb +160 -0
  337. data/test/unit/test_schema_applier.rb +59 -0
  338. data/test/unit/test_sweeper.rb +95 -0
  339. data/test/unit/test_watch_schema.rb +57 -0
  340. data/test/unit/test_watcher.rb +336 -0
  341. metadata +759 -0
data/doc/text/news.md ADDED
@@ -0,0 +1,106 @@
1
+ # News
2
+
3
+ ## 1.0.1: 2014-03-29
4
+
5
+ ### Improvements
6
+
7
+ * More documents around plugin APIs are now available.
8
+ See the plugin [development tutorial](http://droonga.org/tutorial/plugin-development/) and the [plugin API reference](http://droonga.org/reference/plugin/).
9
+ * Some documented features of the `catalog.json` are actually implemented.
10
+ For example:
11
+ * A new `vectorOptions` option for a schema.
12
+ * New options `fact`, `dimension`, `nWorkers` and so on.
13
+ For more details, see [the reference of the `catalog.json`](http://droonga.org/reference/catalog/).
14
+ * Connections to other Droonga Engine nodes are automatically re-established correctly.
15
+ * Some improvements about the [`search` command](http://droonga.org/reference/commands/search/)
16
+ * The column name `_nsubrecs` is available as a source with `groupBy` and `sortBy`.
17
+ * The element `elapsedTime` is now available for a value of `elements`.
18
+ * A new parameter `adjusters` is introduced. (Not documented yet, so see also [Groonga's document](http://groonga.org/docs/reference/commands/select.html#select-adjuster))
19
+ * `groupBy` becomes faster.
20
+ * And some small bugfixes.
21
+
22
+ ## 1.0.0: 2014-02-28
23
+
24
+ ### Improvements
25
+
26
+ * Updated catalog.json specification to
27
+ [version2](http://droonga.org/reference/catalog/version2/).
28
+ [version1](http://droonga.org/reference/catalog/version1/) is
29
+ still usable. But It is deprecated.
30
+ * Supported log API in plugin.
31
+ * Supported auto catalog.json reload.
32
+ * Changed adapter API:
33
+
34
+ Old:
35
+
36
+ message.input_pattern = []
37
+ message.output_pattern = []
38
+
39
+ New:
40
+
41
+ input_message.pattern = []
42
+ output_message.pattern = []
43
+
44
+ * Supported developing a plugin for handling phase.
45
+ See [tutorial](http://droonga.org/tutorial/plugin-development/handler/)
46
+ for details.
47
+
48
+ ## 0.9.9: 2014-02-09
49
+
50
+ ### Improvements
51
+
52
+ * Supported gathering errors.
53
+ * Added more error handled cases.
54
+ * experimental: Added a MeCab filter that filters results from
55
+ N-gram tokenizer based search by MeCab based tokenized search. It
56
+ is disabled by default. You need to define
57
+ `DROONGA_ENABLE_SEARCH_MECAB_FILTER=yes` environment variable when
58
+ you run fluentd.
59
+ * Supported developing a plugin. You can custom adaption phase for now.
60
+ See [tutorial](http://droonga.org/tutorial/plugin-development/) for details.
61
+
62
+ ## 0.9.0: 2014-01-29
63
+
64
+ ### Improvements
65
+
66
+ * `search`: Supported `"attributes"` for `elements` of `output`.
67
+ * `table_remove`: Implemented Groonga compatible `table_remove`
68
+ command.
69
+ * `column_create`: Implemented error handling.
70
+ * `catalog`: Supported auto reloading.
71
+ * Supported reducing responses from two or more nodes for Groonga
72
+ compatible commands.
73
+ * Supported three or more partitions.
74
+
75
+ ## 0.8.0: 2013-12-29
76
+
77
+ ### Improvements
78
+
79
+ * `search`: Supported `groupBy` with multiple partitions.
80
+ * Changed job queue implementation to UNIX domain socket based
81
+ implementation from Groonga's queue based implementation. It
82
+ reduces shutdown time and fixes job queue break problem on
83
+ crash.
84
+ * Supported error response.
85
+ * `watch`: Fixed a bug that duplicated notification is pushed when
86
+ multiple column values are matched.
87
+ * `watch`: Supported subscriber garbage collection.
88
+ * Improved plugin API. Plugin API documentation will be published
89
+ in the next release.
90
+ * Added micro seconds information to time value. It uses W3C-DTF format
91
+ such as `2013-12-29T00:00:00.000000Z`.
92
+ * Changed the name of adapter plugin that provides Groonga's `select`
93
+ compatible API to `groonga` from `select`. The `groonga` adapter will
94
+ provide more Groonga compatible commands.
95
+ * Added `version` to `catalog.json`.
96
+ * Changed plugin path format to
97
+ `droonga/plugin/#{PLUGIN_TYPE}/#{PLUGIN_NAME}.rb` from
98
+ `droonga/plugin/#{PLUGIN_TYPE}_#{PLUGIN_NAME}.rb`. We use a
99
+ directory per plugin type instead of putting all plugins to
100
+ `droonga/plugin/` directory. Because it is more maintainable.
101
+ * Split adapter plugin into input adapter plugin and output adapter
102
+ plugin. You can in the next release.
103
+
104
+ ## 0.7.0: 2013-11-29
105
+
106
+ The first release!!!
@@ -0,0 +1,52 @@
1
+ # -*- mode: ruby; coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013-2014 Droonga Project
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ base_dir = File.dirname(__FILE__)
19
+ $LOAD_PATH.unshift(File.join(base_dir, "lib"))
20
+
21
+ require "droonga/engine/version"
22
+
23
+ Gem::Specification.new do |gem|
24
+ gem.name = "droonga-engine"
25
+ gem.version = Droonga::Engine::VERSION
26
+ gem.authors = ["Droonga Project"]
27
+ gem.email = ["droonga@groonga.org"]
28
+ gem.summary = "Droonga engine"
29
+ gem.description =
30
+ "Droonga engine is a core component in Droonga system. " +
31
+ "Droonga is a scalable data processing engine based on Groonga. " +
32
+ "Droonga means Distributed Groonga."
33
+ gem.homepage = "https://github.com/droonga/droonga-engine"
34
+ gem.files = `git ls-files`.split($/)
35
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
36
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
37
+ gem.require_paths = ["lib"]
38
+ gem.add_dependency "rroonga", ">= 3.1.0"
39
+ gem.add_dependency "groonga-command-parser"
40
+ gem.add_dependency "json"
41
+ gem.add_dependency "cool.io"
42
+ gem.add_dependency "serverengine"
43
+ gem.add_dependency "droonga-message-pack-packer"
44
+ gem.add_development_dependency "rake"
45
+ gem.add_development_dependency "bundler"
46
+ gem.add_development_dependency "droonga-client"
47
+ gem.add_development_dependency "test-unit"
48
+ gem.add_development_dependency "test-unit-notify"
49
+ gem.add_development_dependency "test-unit-rr"
50
+ gem.add_development_dependency "packnga"
51
+ gem.add_development_dependency "kramdown"
52
+ end
@@ -0,0 +1,48 @@
1
+ # Copyright (C) 2014 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ require "droonga/pluggable"
17
+ require "droonga/loggable"
18
+ require "droonga/plugin/metadata/adapter_input_message"
19
+ require "droonga/plugin/metadata/adapter_output_message"
20
+ require "droonga/error_messages"
21
+
22
+ module Droonga
23
+ class Adapter
24
+ extend Pluggable
25
+ include Loggable
26
+ include ErrorMessages
27
+
28
+ class << self
29
+ def input_message
30
+ Plugin::Metadata::AdapterInputMessage.new(self)
31
+ end
32
+
33
+ def output_message
34
+ Plugin::Metadata::AdapterOutputMessage.new(self)
35
+ end
36
+
37
+ def id
38
+ options[:id] || name || object_id.to_s
39
+ end
40
+ end
41
+
42
+ def adapt_input(input_message)
43
+ end
44
+
45
+ def adapt_output(output_message)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,104 @@
1
+ # Copyright (C) 2013-2014 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ require "droonga/loggable"
17
+ require "droonga/message_matcher"
18
+ require "droonga/input_message"
19
+ require "droonga/output_message"
20
+ require "droonga/adapter"
21
+
22
+ module Droonga
23
+ class AdapterRunner
24
+ include Loggable
25
+
26
+ def initialize(dispatcher, plugins)
27
+ @dispatcher = dispatcher
28
+ default_plugins = ["error"]
29
+ plugins += (default_plugins - plugins)
30
+ logger.debug("activating plugins: #{plugins.join(", ")}")
31
+ @adapter_classes = Adapter.find_sub_classes(plugins)
32
+ logger.debug("activated:\n#{@adapter_classes.join("\n")}")
33
+ end
34
+
35
+ def shutdown
36
+ end
37
+
38
+ def adapt_input(message)
39
+ logger.trace("adapt_input: start",
40
+ :dataset => message["dataset"],
41
+ :type => message["type"])
42
+ adapted_message = message
43
+ adapted_message["appliedAdapters"] = []
44
+ @adapter_classes.each do |adapter_class|
45
+ adapter_class_id = adapter_class.id
46
+ pattern = adapter_class.input_message.pattern
47
+ if pattern
48
+ matcher = MessageMatcher.new(pattern)
49
+ logger.trace("adapt_input: skip: #{adapter_class_id}",
50
+ :pattern => pattern)
51
+ next unless matcher.match?(adapted_message)
52
+ end
53
+ logger.trace("adapt_input: use: #{adapter_class_id}")
54
+ input_message = InputMessage.new(adapted_message)
55
+ adapter = adapter_class.new
56
+ adapter.adapt_input(input_message)
57
+ adapted_message = input_message.adapted_message
58
+ adapted_message["appliedAdapters"] << adapter_class_id
59
+ end
60
+ logger.trace("adapt_input: done",
61
+ :dataset => adapted_message["dataset"],
62
+ :type => adapted_message["type"])
63
+ adapted_message
64
+ end
65
+
66
+ def adapt_output(message)
67
+ logger.trace("adapt_output: start",
68
+ :dataset => message["dataset"],
69
+ :type => message["type"])
70
+ adapted_message = message
71
+ applied_adapters = adapted_message["appliedAdapters"]
72
+ @adapter_classes.reverse_each do |adapter_class|
73
+ adapter_class_id = adapter_class.id
74
+ if applied_adapters
75
+ logger.trace("adapt_output: skip: #{adapter_class_id}: " +
76
+ "input adapter wasn't applied",
77
+ :applied_adapters => applied_adapters)
78
+ next unless applied_adapters.include?(adapter_class.id)
79
+ end
80
+ pattern = adapter_class.output_message.pattern
81
+ if pattern
82
+ matcher = MessageMatcher.new(pattern)
83
+ logger.trace("adapt_output: skip: #{adapter_class_id}",
84
+ :pattern => pattern)
85
+ next unless matcher.match?(adapted_message)
86
+ end
87
+ logger.trace("adapt_output: use: #{adapter_class_id}")
88
+ output_message = OutputMessage.new(adapted_message)
89
+ adapter = adapter_class.new
90
+ adapter.adapt_output(output_message)
91
+ adapted_message = output_message.adapted_message
92
+ end
93
+ logger.trace("adapt_output: done",
94
+ :dataset => adapted_message["dataset"],
95
+ :type => adapted_message["type"])
96
+ adapted_message
97
+ end
98
+
99
+ private
100
+ def log_tag
101
+ "adapter-runner"
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,41 @@
1
+ # Copyright (C) 2013-2014 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ require "digest/sha1"
17
+ require "zlib"
18
+ require "time"
19
+ require "droonga/error_messages"
20
+ require "droonga/catalog/errors"
21
+
22
+ module Droonga
23
+ module Catalog
24
+ class Base
25
+ attr_reader :path, :base_path
26
+ def initialize(data, path)
27
+ @data = data
28
+ @path = path
29
+ @base_path = File.dirname(path)
30
+ end
31
+
32
+ def have_dataset?(name)
33
+ datasets.key?(name)
34
+ end
35
+
36
+ def dataset(name)
37
+ datasets[name]
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,106 @@
1
+ # Copyright (C) 2014 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ require "digest/sha1"
17
+ require "zlib"
18
+
19
+ require "droonga/catalog/slice"
20
+
21
+ module Droonga
22
+ module Catalog
23
+ class CollectionVolume
24
+ def initialize(dataset, data)
25
+ @dataset = dataset
26
+ @data = data
27
+ compute_continuum if ratio_scaled_slicer?
28
+ end
29
+
30
+ def dimension
31
+ @data["dimension"] || "_key"
32
+ end
33
+
34
+ def slicer
35
+ @data["slicer"] || "hash"
36
+ end
37
+
38
+ def slices
39
+ @slices ||= @data["slices"].collect do |raw_slice|
40
+ Slice.new(@dataset, raw_slice)
41
+ end
42
+ end
43
+
44
+ def select_slices(range=0..-1)
45
+ slices.sort_by(&:label)[range]
46
+ end
47
+
48
+ def choose_slice(record)
49
+ return slices.first unless ratio_scaled_slicer?
50
+
51
+ key = stringify_key(record[dimension])
52
+ hash = Zlib.crc32(key)
53
+ min = 0
54
+ max = @continuum.size - 1
55
+ while (min < max)
56
+ index = (min + max) / 2
57
+ value, key = @continuum[index]
58
+ return key if value == hash
59
+ if value > hash
60
+ max = index
61
+ else
62
+ min = index + 1
63
+ end
64
+ end
65
+ @continuum[max][1]
66
+ end
67
+
68
+ def ratio_scaled_slicer?
69
+ slicer == "hash"
70
+ end
71
+
72
+ private
73
+ def compute_continuum
74
+ total_weight = compute_total_weight
75
+ continuum = []
76
+ n_slices = slices.size
77
+ slices.each do |slice|
78
+ weight = slice.weight
79
+ points = n_slices * 160 * weight / total_weight
80
+ points.times do |point|
81
+ hash = Digest::SHA1.hexdigest("#{@dataset.name}:#{point}")
82
+ continuum << [hash[0..7].to_i(16), slice]
83
+ end
84
+ end
85
+ @continuum = continuum.sort do |a, b|
86
+ a[0] - b[0]
87
+ end
88
+ end
89
+
90
+ def compute_total_weight
91
+ slices.reduce(0) do |result, slice|
92
+ result + slice.weight
93
+ end
94
+ end
95
+
96
+ def stringify_key(key)
97
+ case key
98
+ when Integer
99
+ key.to_s
100
+ else
101
+ key
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,69 @@
1
+ # Copyright (C) 2014 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ require "droonga/catalog/schema"
17
+ require "droonga/catalog/volume"
18
+ require "droonga/catalog/volume_collection"
19
+
20
+ module Droonga
21
+ module Catalog
22
+ class Dataset
23
+ attr_reader :name
24
+
25
+ def initialize(name, data)
26
+ @name = name
27
+ @data = data
28
+ @schema = nil
29
+ end
30
+
31
+ # provided for compatibility
32
+ def [](key)
33
+ @data[key]
34
+ end
35
+
36
+ # provided for compatibility
37
+ def []=(key, value)
38
+ @data[key] = value
39
+ end
40
+
41
+ def schema
42
+ @schema ||= Schema.new(@name, @data["schema"])
43
+ end
44
+
45
+ def plugins
46
+ @data["plugins"] || []
47
+ end
48
+
49
+ def fact
50
+ @data["fact"]
51
+ end
52
+
53
+ def n_workers
54
+ @data["nWorkers"] || 0
55
+ end
56
+
57
+ def replicas
58
+ @replicas ||= VolumeCollection.new(create_volumes(@data["replicas"]))
59
+ end
60
+
61
+ private
62
+ def create_volumes(raw_volumes)
63
+ raw_volumes.collect do |raw_volume|
64
+ Volume.create(self, raw_volume)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,113 @@
1
+ # Copyright (C) 2014 Droonga Project
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ require "droonga/error"
17
+
18
+ module Droonga
19
+ module Catalog
20
+ class ValidationError < Error
21
+ class Detail
22
+ attr_reader :value_path, :message
23
+ def initialize(value_path, message)
24
+ @value_path = value_path
25
+ @message = message
26
+ end
27
+ end
28
+
29
+ attr_reader :path, :details
30
+ def initialize(path, details)
31
+ message = "validation error: <#{path}>"
32
+ details.each do |detail|
33
+ message << "\n * #{detail.value_path}: #{detail.message}"
34
+ end
35
+ super(message)
36
+ end
37
+ end
38
+
39
+ class LegacyValidationError < Error
40
+ def initialize(message, path)
41
+ if path
42
+ super("[Validation Error <#{path}>]#{message}")
43
+ else
44
+ super(message)
45
+ end
46
+ end
47
+ end
48
+
49
+ class MissingRequiredParameter < LegacyValidationError
50
+ def initialize(name, path)
51
+ super("[#{name}] A required parameter is missing.", path)
52
+ end
53
+ end
54
+
55
+ class MismatchedParameterType < LegacyValidationError
56
+ def initialize(name, expected_types, actual, path)
57
+ expected_types = [expected_types] unless expected_types.is_a?(Array)
58
+ message = nil
59
+ if expected_types.size == 1
60
+ message = "[#{name}] Mismatched parameter type: " +
61
+ "expected=<#{expected_types.first}>, actual=<#{actual}>"
62
+ else
63
+ message = "[#{name}] Mismatched parameter type: " +
64
+ "expected=<#{expected_types.join(" or ")}>, " +
65
+ "actual=<#{actual}>"
66
+ end
67
+ super(message, path)
68
+ end
69
+ end
70
+
71
+ class InvalidDate < LegacyValidationError
72
+ def initialize(name, value, path)
73
+ super("[#{name}] Invalid date string: <#{value}>", path)
74
+ end
75
+ end
76
+
77
+ class NegativeNumber < LegacyValidationError
78
+ def initialize(name, actual, path)
79
+ super("[#{name}] A positive number is expected, but <#{actual}>", path)
80
+ end
81
+ end
82
+
83
+ class SmallerThanOne < LegacyValidationError
84
+ def initialize(name, actual, path)
85
+ super("[#{name}] A number 1 or larger is expected, but <#{actual}>", path)
86
+ end
87
+ end
88
+
89
+ class FarmNotZoned < LegacyValidationError
90
+ def initialize(name, zones, path)
91
+ super("The farm does not appear in zones: <#{name}>, zones=<#{zones}>", path)
92
+ end
93
+ end
94
+
95
+ class UnknownFarmInZones < LegacyValidationError
96
+ def initialize(name, zones, path)
97
+ super("The farm is unknown: <#{name}>, zones=<#{zones}>", path)
98
+ end
99
+ end
100
+
101
+ class UnknownFarmForPartition < LegacyValidationError
102
+ def initialize(name, slice, path)
103
+ super("The farm is unknown: <{#name}>, slice=<#{slice}>", path)
104
+ end
105
+ end
106
+
107
+ class UnsupportedValue < LegacyValidationError
108
+ def initialize(name, value, path)
109
+ super("[#{name}] Not supported value: <#{value}>", path)
110
+ end
111
+ end
112
+ end
113
+ end