droonga-engine 1.0.2 → 1.0.3

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 (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