droonga-engine 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +7 -0
  5. data/Rakefile +6 -2
  6. data/bin/droonga-engine +2 -2
  7. data/bin/{droonga-catalog-generate → droonga-engine-catalog-generate} +15 -3
  8. data/bin/droonga-engine-serf-event-handler +20 -0
  9. data/bin/droonga-engine-service +2 -2
  10. data/doc/text/news.md +21 -1
  11. data/droonga-engine.gemspec +5 -2
  12. data/lib/droonga/catalog/collection_volume.rb +12 -0
  13. data/lib/droonga/catalog/dataset.rb +25 -0
  14. data/lib/droonga/catalog/single_volume.rb +10 -0
  15. data/lib/droonga/catalog/slice.rb +4 -0
  16. data/lib/droonga/catalog/version1.rb +59 -48
  17. data/lib/droonga/catalog/version2.rb +10 -20
  18. data/lib/droonga/catalog/volume_collection.rb +27 -4
  19. data/lib/droonga/catalog_generator.rb +12 -5
  20. data/lib/droonga/catalog_observer.rb +17 -35
  21. data/lib/droonga/command/droonga_engine.rb +436 -0
  22. data/lib/droonga/command/droonga_engine_service.rb +273 -0
  23. data/lib/droonga/command/serf_event_handler.rb +85 -0
  24. data/lib/droonga/dispatcher.rb +8 -8
  25. data/lib/droonga/engine.rb +90 -26
  26. data/lib/droonga/engine/version.rb +1 -1
  27. data/lib/droonga/engine_state.rb +29 -3
  28. data/lib/droonga/internal_fluent_message_receiver.rb +100 -0
  29. data/lib/droonga/live_nodes_list_loader.rb +48 -0
  30. data/lib/droonga/live_nodes_list_observer.rb +72 -0
  31. data/lib/droonga/path.rb +47 -0
  32. data/lib/droonga/plugins/dump.rb +279 -38
  33. data/lib/droonga/plugins/groonga/select.rb +26 -14
  34. data/lib/droonga/plugins/search.rb +30 -2
  35. data/lib/droonga/plugins/search/distributed_search_planner.rb +28 -11
  36. data/lib/droonga/processor.rb +4 -0
  37. data/lib/droonga/searcher.rb +26 -0
  38. data/lib/droonga/serf.rb +119 -0
  39. data/lib/droonga/serf_downloader.rb +90 -0
  40. data/lib/droonga/server.rb +2 -2
  41. data/lib/droonga/service_control_protocol.rb +26 -0
  42. data/sample/cluster/catalog.json +1 -1
  43. data/test/command/config/default/catalog.json +2 -2
  44. data/test/command/config/version1/catalog.json +1 -1
  45. data/test/command/fixture/documents.jsons +18 -18
  46. data/test/command/fixture/event.jsons +4 -4
  47. data/test/command/fixture/user-table-array.jsons +4 -4
  48. data/test/command/fixture/user-table.jsons +5 -5
  49. data/test/command/suite/add/dimension/column.catalog.json +1 -1
  50. data/test/command/suite/add/dimension/column.test +4 -4
  51. data/test/command/suite/add/dimension/integer.catalog.json +1 -1
  52. data/test/command/suite/add/dimension/integer.test +4 -4
  53. data/test/command/suite/add/error/invalid-integer.test +1 -1
  54. data/test/command/suite/add/error/invalid-time.test +1 -1
  55. data/test/command/suite/add/error/missing-key.test +1 -1
  56. data/test/command/suite/add/error/missing-table.test +1 -1
  57. data/test/command/suite/add/error/unknown-column.test +1 -1
  58. data/test/command/suite/add/error/unknown-table.test +1 -1
  59. data/test/command/suite/add/minimum.test +1 -1
  60. data/test/command/suite/add/vector/short_text.catalog.json +26 -0
  61. data/test/command/suite/add/vector/short_text.expected +42 -0
  62. data/test/command/suite/add/vector/short_text.test +35 -0
  63. data/test/command/suite/add/with-values.test +1 -1
  64. data/test/command/suite/add/without-key.test +1 -1
  65. data/test/command/suite/dump/column/index.catalog.json +40 -0
  66. data/test/command/suite/dump/column/index.expected +195 -0
  67. data/test/command/suite/dump/column/index.test +5 -0
  68. data/test/command/suite/dump/column/scalar.catalog.json +19 -0
  69. data/test/command/suite/dump/column/scalar.expected +99 -0
  70. data/test/command/suite/dump/column/scalar.test +5 -0
  71. data/test/command/suite/dump/column/vector.catalog.json +22 -0
  72. data/test/command/suite/dump/column/vector.expected +108 -0
  73. data/test/command/suite/dump/column/vector.test +5 -0
  74. data/test/command/suite/dump/record/vector/reference.catalog.json +27 -0
  75. data/test/command/suite/dump/record/vector/reference.expected +213 -0
  76. data/test/command/suite/dump/record/vector/reference.test +21 -0
  77. data/test/command/suite/dump/table/array.catalog.json +13 -0
  78. data/test/command/suite/dump/table/array.expected +63 -0
  79. data/test/command/suite/dump/table/array.test +5 -0
  80. data/test/command/suite/dump/table/double_array_trie.catalog.json +14 -0
  81. data/test/command/suite/dump/table/double_array_trie.expected +66 -0
  82. data/test/command/suite/dump/table/double_array_trie.test +5 -0
  83. data/test/command/suite/dump/table/hash.catalog.json +14 -0
  84. data/test/command/suite/dump/table/hash.expected +66 -0
  85. data/test/command/suite/dump/table/hash.test +5 -0
  86. data/test/command/suite/dump/table/patricia_trie.catalog.json +14 -0
  87. data/test/command/suite/dump/table/patricia_trie.expected +66 -0
  88. data/test/command/suite/dump/table/patricia_trie.test +5 -0
  89. data/test/command/suite/groonga/column_create/scalar.test +2 -2
  90. data/test/command/suite/groonga/column_create/unknown-table.test +1 -1
  91. data/test/command/suite/groonga/column_create/vector.test +2 -2
  92. data/test/command/suite/groonga/column_list/success.test +3 -3
  93. data/test/command/suite/groonga/column_list/unknown-table.test +1 -1
  94. data/test/command/suite/groonga/column_remove/success.test +3 -3
  95. data/test/command/suite/groonga/column_remove/unknown-column.test +2 -2
  96. data/test/command/suite/groonga/column_remove/unknown-table.test +1 -1
  97. data/test/command/suite/groonga/column_rename/success.test +3 -3
  98. data/test/command/suite/groonga/column_rename/unknown-column.test +2 -2
  99. data/test/command/suite/groonga/column_rename/unknown-table.test +1 -1
  100. data/test/command/suite/groonga/delete/duplicated-identifiers.test +2 -2
  101. data/test/command/suite/groonga/delete/filter.test +2 -2
  102. data/test/command/suite/groonga/delete/invalid-filter.test +1 -1
  103. data/test/command/suite/groonga/delete/no-identifier.test +2 -2
  104. data/test/command/suite/groonga/delete/success.test +2 -2
  105. data/test/command/suite/groonga/delete/unknown-table.test +1 -1
  106. data/test/command/suite/groonga/select/minimum.expected +24 -1
  107. data/test/command/suite/groonga/select/minimum.test +1 -1
  108. data/test/command/suite/groonga/select/type/time.catalog.json +19 -0
  109. data/test/command/suite/groonga/select/type/time.expected +37 -0
  110. data/test/command/suite/groonga/select/type/time.test +35 -0
  111. data/test/command/suite/groonga/table_create/array.test +1 -1
  112. data/test/command/suite/groonga/table_create/hash.test +1 -1
  113. data/test/command/suite/groonga/table_list/success.test +2 -2
  114. data/test/command/suite/groonga/table_remove/success.test +1 -1
  115. data/test/command/suite/groonga/table_remove/unknown-table.test +1 -1
  116. data/test/command/suite/message/error/unknown-type.expected +1 -1
  117. data/test/command/suite/message/error/unknown-type.test +1 -1
  118. data/test/command/suite/search/adjusters/multiple.catalog.json +1 -1
  119. data/test/command/suite/search/adjusters/multiple.test +3 -3
  120. data/test/command/suite/search/adjusters/one.catalog.json +1 -1
  121. data/test/command/suite/search/adjusters/one.test +3 -3
  122. data/test/command/suite/search/attributes/array.expected +7 -0
  123. data/test/command/suite/search/attributes/array.test +1 -1
  124. data/test/command/suite/search/attributes/hash.expected +18 -0
  125. data/test/command/suite/search/attributes/hash.test +1 -1
  126. data/test/command/suite/search/complex.expected +12 -0
  127. data/test/command/suite/search/complex.test +1 -1
  128. data/test/command/suite/search/condition/nested.catalog.json +37 -0
  129. data/test/command/suite/search/condition/nested.expected +7 -0
  130. data/test/command/suite/search/condition/nested.test +103 -2
  131. data/test/command/suite/search/condition/query.catalog.json +37 -0
  132. data/test/command/suite/search/condition/query.expected +7 -0
  133. data/test/command/suite/search/condition/query.test +103 -2
  134. data/test/command/suite/search/condition/query/nonexistent_column.catalog.json +1 -1
  135. data/test/command/suite/search/condition/query/nonexistent_column.test +2 -2
  136. data/test/command/suite/search/condition/query/syntax_error.catalog.json +1 -1
  137. data/test/command/suite/search/condition/query/syntax_error.test +2 -2
  138. data/test/command/suite/search/condition/script.catalog.json +37 -0
  139. data/test/command/suite/search/condition/script.expected +7 -0
  140. data/test/command/suite/search/condition/script.test +103 -2
  141. data/test/command/suite/search/error/cyclic-source.test +1 -1
  142. data/test/command/suite/search/error/deeply-cyclic-source.test +1 -1
  143. data/test/command/suite/search/error/missing-source-parameter.test +1 -1
  144. data/test/command/suite/search/error/no-query.test +1 -1
  145. data/test/command/suite/search/error/unknown-source.test +1 -1
  146. data/test/command/suite/search/group/count.test +1 -1
  147. data/test/command/suite/search/group/limit.test +1 -1
  148. data/test/command/suite/search/group/string.catalog.json +41 -0
  149. data/test/command/suite/search/group/string.expected +18 -18
  150. data/test/command/suite/search/group/string.test +67 -22
  151. data/test/command/suite/search/group/subrecord/with-sort.catalog.json +1 -1
  152. data/test/command/suite/search/group/subrecord/with-sort.test +5 -5
  153. data/test/command/suite/search/multiple/chained.catalog.json +37 -0
  154. data/test/command/suite/search/multiple/chained.expected +14 -0
  155. data/test/command/suite/search/multiple/chained.test +103 -2
  156. data/test/command/suite/search/multiple/parallel.expected +14 -0
  157. data/test/command/suite/search/multiple/parallel.test +1 -1
  158. data/test/command/suite/search/output/attributes/invalid.catalog.json +1 -1
  159. data/test/command/suite/search/output/attributes/invalid.test +2 -2
  160. data/test/command/suite/search/output/attributes/star.catalog.json +23 -0
  161. data/test/command/suite/search/output/attributes/star.expected +27 -0
  162. data/test/command/suite/search/output/attributes/star.test +32 -0
  163. data/test/command/suite/search/range/only-output.expected +7 -0
  164. data/test/command/suite/search/range/only-output.test +1 -1
  165. data/test/command/suite/search/range/only-sort.expected +7 -0
  166. data/test/command/suite/search/range/only-sort.test +1 -1
  167. data/test/command/suite/search/range/sort-and-output.expected +7 -0
  168. data/test/command/suite/search/range/sort-and-output.test +1 -1
  169. data/test/command/suite/search/range/too-large-output-offset.expected +8 -0
  170. data/test/command/suite/search/range/too-large-output-offset.test +1 -1
  171. data/test/command/suite/search/range/too-large-sort-offset.expected +8 -0
  172. data/test/command/suite/search/range/too-large-sort-offset.test +1 -1
  173. data/test/command/suite/search/response/elapsed_time.catalog.json +1 -1
  174. data/test/command/suite/search/response/elapsed_time.test +2 -2
  175. data/test/command/suite/search/response/records/value/time.expected +12 -0
  176. data/test/command/suite/search/response/records/value/time.test +1 -1
  177. data/test/command/suite/search/simple.expected +12 -0
  178. data/test/command/suite/search/simple.test +1 -1
  179. data/test/command/suite/search/sort/default-offset-limit.expected +7 -0
  180. data/test/command/suite/search/sort/default-offset-limit.test +1 -1
  181. data/test/command/suite/search/sort/invisible-column.expected +7 -0
  182. data/test/command/suite/search/sort/invisible-column.test +1 -1
  183. data/test/unit/catalog/test_collection_volume.rb +16 -0
  184. data/test/unit/catalog/test_dataset.rb +36 -0
  185. data/test/unit/catalog/test_single_volume.rb +9 -0
  186. data/test/unit/catalog/test_slice.rb +11 -0
  187. data/test/unit/catalog/test_version1.rb +7 -12
  188. data/test/unit/catalog/test_version2.rb +7 -0
  189. data/test/unit/catalog/test_volume_collection.rb +28 -0
  190. data/test/unit/fixtures/catalog/version1.json +10 -3
  191. data/test/unit/fixtures/catalog/version2.json +2 -2
  192. data/test/unit/plugins/groonga/select/test_adapter_output.rb +8 -14
  193. data/test/unit/plugins/groonga/test_column_create.rb +5 -5
  194. data/test/unit/plugins/groonga/test_column_remove.rb +2 -2
  195. data/test/unit/plugins/groonga/test_column_rename.rb +2 -2
  196. data/test/unit/plugins/groonga/test_delete.rb +2 -2
  197. data/test/unit/plugins/groonga/test_table_create.rb +9 -9
  198. data/test/unit/plugins/groonga/test_table_remove.rb +1 -1
  199. data/test/unit/test_catalog_generator.rb +1 -1
  200. data/test/unit/test_schema_applier.rb +2 -2
  201. data/test/unit/test_watch_schema.rb +4 -4
  202. metadata +241 -72
  203. data/lib/droonga/engine/command/droonga_engine.rb +0 -441
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d592eda2e4916fb9d0d4fbf48ad538cbff3c1d34
4
+ data.tar.gz: 62255e98b9141709a42db836e525737a8e254343
5
+ SHA512:
6
+ metadata.gz: 163a844fae7ba67af1dc934380a374756439744e844de81e53fe9dc141f6a7b1ad457db25a0e7a1fda988d6709aab34e55b9ecd0efc3dabb6c6be508bf6fb466
7
+ data.tar.gz: 183c9afe679f550c198e65f9f7f5dfab74b10ded4e84bfd40d1b93239227c571063e05920aa6e514eaa11a46a35cdad8f320265f60534b6944071c2132e79e94
data/.gitignore CHANGED
@@ -4,3 +4,4 @@
4
4
  /.yardoc/
5
5
  /pkg/
6
6
  /sample/cluster/0*
7
+ /sample/cluster/state/
data/.travis.yml CHANGED
@@ -13,3 +13,6 @@ rvm:
13
13
  before_install:
14
14
  # - GROONGA_MASTER=yes curl --silent --location https://raw.github.com/groonga/groonga/master/data/travis/setup.sh | sh
15
15
  - curl --silent --location https://raw.github.com/groonga/groonga/master/data/travis/setup.sh | sh
16
+ - curl --location --remote-name https://dl.bintray.com/mitchellh/serf/0.6.0_linux_amd64.zip
17
+ - unzip 0.6.0_linux_amd64.zip
18
+ - sudo install serf /usr/local/bin/
data/Gemfile CHANGED
@@ -37,6 +37,13 @@ elsif ENV["TRAVIS"] == "true"
37
37
  end
38
38
  end
39
39
 
40
+ droonga_message_pack_packer_dir = File.join(parent_dir, "droonga-message-pack-packer-ruby")
41
+ if File.exist?(droonga_message_pack_packer_dir)
42
+ gem "droonga-message-pack-packer", :path => droonga_message_pack_packer_dir
43
+ else
44
+ gem "droonga-message-pack-packer", :github => "droonga/droonga-message-pack-packer-ruby"
45
+ end
46
+
40
47
  droonga_client_dir = File.join(parent_dir, "droonga-client-ruby")
41
48
  if File.exist?(droonga_client_dir)
42
49
  gem "droonga-client", :path => droonga_client_dir
data/Rakefile CHANGED
@@ -30,8 +30,12 @@ Packnga::DocumentTask.new(spec) do |task|
30
30
  end
31
31
 
32
32
  def run_command_test(*options)
33
- ruby(File.join(File.dirname(__FILE__), "test", "command", "run-test.rb",),
34
- *options)
33
+ default_options = []
34
+ if ENV["TRAVIS"] == "true"
35
+ default_options.push("--timeout", "3")
36
+ end
37
+ ruby(File.join(File.dirname(__FILE__), "test", "command", "run-test.rb"),
38
+ *(default_options + options))
35
39
  end
36
40
 
37
41
  namespace :test do
data/bin/droonga-engine CHANGED
@@ -15,6 +15,6 @@
15
15
  # License along with this library; if not, write to the Free Software
16
16
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 
18
- require "droonga/engine/command/droonga_engine"
18
+ require "droonga/command/droonga_engine"
19
19
 
20
- exit(Droonga::Engine::Command::DroongaEngine::Supervisor.run(ARGV))
20
+ exit(Droonga::Command::DroongaEngine.run(ARGV))
@@ -18,13 +18,17 @@
18
18
  require "ostruct"
19
19
  require "optparse"
20
20
  require "json"
21
+ require "tempfile"
22
+ require "pathname"
21
23
 
22
24
  require "droonga/engine/version"
23
25
  require "droonga/catalog_generator"
24
26
 
25
27
  generator = Droonga::CatalogGenerator.new
26
- current_dataset = nil
27
- datasets = {}
28
+ current_dataset = {}
29
+ datasets = {
30
+ Droonga::CatalogGenerator::DEFAULT_DATASET => current_dataset
31
+ }
28
32
 
29
33
  options = OpenStruct.new
30
34
  options.output_path = "-"
@@ -83,6 +87,10 @@ parser.on("--replicas=PATH",
83
87
  end
84
88
  parser.parse!(ARGV)
85
89
 
90
+ if datasets[Droonga::CatalogGenerator::DEFAULT_DATASET].empty?
91
+ datasets.delete(Droonga::CatalogGenerator::DEFAULT_DATASET)
92
+ end
93
+
86
94
  datasets.each do |name, options|
87
95
  generator.add_dataset(name, options)
88
96
  end
@@ -91,8 +99,12 @@ def open_output(path)
91
99
  if path == "-"
92
100
  yield($stdout)
93
101
  else
94
- File.open(path, "w") do |output|
102
+ # Don't output the file directly to prevent loading of incomplete file!
103
+ path = Pathname(path).expand_path
104
+ Tempfile.open(path.basename.to_s, path.parent.to_s, "w") do |output|
95
105
  yield(output)
106
+ output.flush
107
+ File.rename(output.path, path.to_s)
96
108
  end
97
109
  end
98
110
  end
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright (C) 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
+ require "droonga/command/serf_event_handler"
19
+
20
+ exit(Droonga::Command::SerfEventHandler.run)
@@ -15,6 +15,6 @@
15
15
  # License along with this library; if not, write to the Free Software
16
16
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
 
18
- require "droonga/engine/command/droonga_engine"
18
+ require "droonga/command/droonga_engine_service"
19
19
 
20
- exit(Droonga::Engine::Command::DroongaEngine::Service.run(ARGV))
20
+ exit(Droonga::Command::DroongaEngineService.run(ARGV))
data/doc/text/news.md CHANGED
@@ -1,6 +1,26 @@
1
1
  # News
2
2
 
3
- ## 1.0.2: 2014-04-29 (planned)
3
+ ## 1.0.3: 2014-05-29
4
+
5
+ * Alive monitoring (based on [Serf](http://serfdom.io/)) lands.
6
+ Now, nodes in a cluster observe each other, and the cluster keeps working, even if one of replicas is dead.
7
+ * New commands to dump whole contents of an existing cluster are available.
8
+ They are used by [`drndump`](https://github.com/droonga/drndump) internally.
9
+ * The command line tool `droonga-catalog-generate` is renamed to `droonga-engine-catalog-generate`.
10
+ * Use `Default` as the name of the default dataset for a `catalog.json`, generated by `droonga-catalog-generate` .
11
+ * The path of the configuration directory is now specified via an environment variable `DROONGA_BASE_DIR`.
12
+ * Fix incompatibilities of the `select` Groonga command.
13
+ * The default value of the `drilldown_output_columns` option becomes same to Groonga's one.
14
+ * Column values of `Time` type clumns are returned as float numbers correctly.
15
+ * The message structure of results becomes same to Groonga.
16
+ In previous version, records are wrongly wrapped in an array.
17
+ * Improve features of the `select` command..
18
+ * The request parameter `"attributes"` for `"elements"` in `"output"` is now available.
19
+ * The special value `"*"` for `"attributes"` in `"output"` is now available, to export all columns.
20
+ * Server process does shutdown/restart gracefully.
21
+ * Restart itself automatically when the `catalog.json` is updated.
22
+
23
+ ## 1.0.2: 2014-04-29
4
24
 
5
25
  The most important topic on this release is that the core component aka Droonga Engine becomes fluentd-free.
6
26
  As the result, the project (and gem package) `fluent-plugin-droonga` is renamed to `droonga-engine`.
@@ -40,10 +40,13 @@ Gem::Specification.new do |gem|
40
40
  gem.add_dependency "json"
41
41
  gem.add_dependency "cool.io"
42
42
  gem.add_dependency "serverengine"
43
- gem.add_dependency "droonga-message-pack-packer"
43
+ gem.add_dependency "droonga-message-pack-packer", ">= 1.0.1"
44
+ gem.add_dependency "listen", "~> 2.7"
45
+ gem.add_dependency "faraday"
46
+ gem.add_dependency "faraday_middleware"
47
+ gem.add_dependency "archive-zip"
44
48
  gem.add_development_dependency "rake"
45
49
  gem.add_development_dependency "bundler"
46
- gem.add_development_dependency "droonga-client"
47
50
  gem.add_development_dependency "test-unit"
48
51
  gem.add_development_dependency "test-unit-notify"
49
52
  gem.add_development_dependency "test-unit-rr"
@@ -69,6 +69,10 @@ module Droonga
69
69
  slicer == "hash"
70
70
  end
71
71
 
72
+ def all_nodes
73
+ @all_nodes ||= collect_all_nodes
74
+ end
75
+
72
76
  private
73
77
  def compute_continuum
74
78
  total_weight = compute_total_weight
@@ -101,6 +105,14 @@ module Droonga
101
105
  key
102
106
  end
103
107
  end
108
+
109
+ def collect_all_nodes
110
+ nodes = []
111
+ slices.each do |slice|
112
+ nodes += slice.all_nodes
113
+ end
114
+ nodes.uniq.sort
115
+ end
104
116
  end
105
117
  end
106
118
  end
@@ -58,6 +58,31 @@ module Droonga
58
58
  @replicas ||= VolumeCollection.new(create_volumes(@data["replicas"]))
59
59
  end
60
60
 
61
+ def all_nodes
62
+ @all_nodes ||= replicas.all_nodes
63
+ end
64
+
65
+ def get_routes(args, live_nodes=nil)
66
+ routes = []
67
+ case args["type"]
68
+ when "broadcast"
69
+ volumes = replicas.select(args["replica"].to_sym, live_nodes)
70
+ volumes.each do |volume|
71
+ slices = volume.select_slices
72
+ slices.each do |slice|
73
+ routes << slice.volume.address
74
+ end
75
+ end
76
+ when "scatter"
77
+ volumes = replicas.select(args["replica"].to_sym, live_nodes)
78
+ volumes.each do |volume|
79
+ slice = volume.choose_slice(args["record"])
80
+ routes << slice.volume.address
81
+ end
82
+ end
83
+ routes
84
+ end
85
+
61
86
  private
62
87
  def create_volumes(raw_volumes)
63
88
  raw_volumes.collect do |raw_volume|
@@ -23,6 +23,16 @@ module Droonga
23
23
  def address
24
24
  @data["address"]
25
25
  end
26
+
27
+ def node
28
+ ip_address_and_port, path = address.split("/")
29
+ tag = path.split(".").first
30
+ "#{ip_address_and_port}/#{tag}"
31
+ end
32
+
33
+ def all_nodes
34
+ @all_nodes ||= [node]
35
+ end
26
36
  end
27
37
  end
28
38
  end
@@ -36,6 +36,10 @@ module Droonga
36
36
  def volume
37
37
  @volume ||= Volume.create(@dataset, @data["volume"])
38
38
  end
39
+
40
+ def all_nodes
41
+ @all_nodes ||= volume.all_nodes
42
+ end
39
43
  end
40
44
  end
41
45
  end
@@ -13,6 +13,8 @@
13
13
  # License along with this library; if not, write to the Free Software
14
14
  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
15
 
16
+ require "English"
17
+
16
18
  require "droonga/catalog/base"
17
19
  require "droonga/catalog/dataset"
18
20
 
@@ -66,53 +68,8 @@ module Droonga
66
68
  return results
67
69
  end
68
70
 
69
- def get_routes(name, args)
70
- routes = []
71
- dataset = dataset(name)
72
- case args["type"]
73
- when "broadcast"
74
- dataset["ring"].each do |key, partition|
75
- select_range_and_replicas(partition, args, routes)
76
- end
77
- when "scatter"
78
- name = get_partition(dataset, args["record"]["_key"])
79
- partition = dataset["ring"][name]
80
- select_range_and_replicas(partition, args, routes)
81
- end
82
- return routes
83
- end
84
-
85
- def get_partition(dataset, key)
86
- continuum = dataset["continuum"]
87
- return dataset["ring"].keys[0] unless continuum
88
- hash = Zlib.crc32(key)
89
- min = 0
90
- max = continuum.size - 1
91
- while (min < max) do
92
- index = (min + max) / 2
93
- value, key = continuum[index]
94
- return key if value == hash
95
- if value > hash
96
- max = index
97
- else
98
- min = index + 1
99
- end
100
- end
101
- return continuum[max][1]
102
- end
103
-
104
- def select_range_and_replicas(partition, args, routes)
105
- date_range = args["date_range"] || 0..-1
106
- partition["partitions"].sort[date_range].each do |time, replicas|
107
- case args["replica"]
108
- when "top"
109
- routes << replicas[0]
110
- when "random"
111
- routes << replicas[rand(replicas.size)]
112
- when "all"
113
- routes.concat(replicas)
114
- end
115
- end
71
+ def all_nodes
72
+ @all_nodes ||= collect_all_nodes
116
73
  end
117
74
 
118
75
  private
@@ -142,6 +99,10 @@ module Droonga
142
99
  end
143
100
  end
144
101
 
102
+ def collect_all_nodes
103
+ @data["zones"].sort
104
+ end
105
+
145
106
  def validate
146
107
  do_validation do
147
108
  validate_effective_date
@@ -408,8 +369,8 @@ module Droonga
408
369
  unless partition =~ valid_farms_matcher
409
370
  raise UnknownFarmForPartition.new(name, partition, @path)
410
371
  end
372
+ directory_name = $POSTMATCH
411
373
  do_validation do
412
- directory_name = $POSTMATCH
413
374
  if directory_name.nil? or directory_name.empty?
414
375
  message = "\"#{partition}\" has no database name. " +
415
376
  "You mus specify a database name for \"#{name}\"."
@@ -422,6 +383,56 @@ module Droonga
422
383
  end
423
384
  end
424
385
  end
386
+
387
+ class Dataset < Catalog::Dataset
388
+ def get_routes(args, live_nodes=nil)
389
+ routes = []
390
+ case args["type"]
391
+ when "broadcast"
392
+ self["ring"].each do |key, partition|
393
+ select_range_and_replicas(partition, args, routes)
394
+ end
395
+ when "scatter"
396
+ name = get_partition(args["record"]["_key"])
397
+ partition = self["ring"][name]
398
+ select_range_and_replicas(partition, args, routes)
399
+ end
400
+ return routes
401
+ end
402
+
403
+ def get_partition(key)
404
+ continuum = self["continuum"]
405
+ return self["ring"].keys[0] unless continuum
406
+ hash = Zlib.crc32(key)
407
+ min = 0
408
+ max = continuum.size - 1
409
+ while (min < max) do
410
+ index = (min + max) / 2
411
+ value, key = continuum[index]
412
+ return key if value == hash
413
+ if value > hash
414
+ max = index
415
+ else
416
+ min = index + 1
417
+ end
418
+ end
419
+ return continuum[max][1]
420
+ end
421
+
422
+ def select_range_and_replicas(partition, args, routes)
423
+ date_range = args["date_range"] || 0..-1
424
+ partition["partitions"].sort[date_range].each do |time, replicas|
425
+ case args["replica"]
426
+ when "top"
427
+ routes << replicas[0]
428
+ when "random"
429
+ routes << replicas[rand(replicas.size)]
430
+ when "all"
431
+ routes.concat(replicas)
432
+ end
433
+ end
434
+ end
435
+ end
425
436
  end
426
437
  end
427
438
  end
@@ -57,26 +57,8 @@ module Droonga
57
57
  results
58
58
  end
59
59
 
60
- def get_routes(name, args)
61
- routes = []
62
- dataset = dataset(name)
63
- case args["type"]
64
- when "broadcast"
65
- volumes = dataset.replicas.select(args["replica"].to_sym)
66
- volumes.each do |volume|
67
- slices = volume.select_slices
68
- slices.each do |slice|
69
- routes << slice.volume.address
70
- end
71
- end
72
- when "scatter"
73
- volumes = dataset.replicas.select(args["replica"].to_sym)
74
- volumes.each do |volume|
75
- slice = volume.choose_slice(args["record"])
76
- routes << slice.volume.address
77
- end
78
- end
79
- routes
60
+ def all_nodes
61
+ @all_nodes ||= collect_all_nodes
80
62
  end
81
63
 
82
64
  private
@@ -91,6 +73,14 @@ module Droonga
91
73
  @datasets[name] = Dataset.new(name, dataset)
92
74
  end
93
75
  end
76
+
77
+ def collect_all_nodes
78
+ nodes = []
79
+ @datasets.each do |name, dataset|
80
+ nodes += dataset.all_nodes
81
+ end
82
+ nodes.sort.uniq
83
+ end
94
84
  end
95
85
  end
96
86
  end