droonga-engine 1.0.9 → 1.1.0

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 (195) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/benchmark/timer-watcher/benchmark.rb +44 -0
  4. data/bin/droonga-engine-absorb-data +246 -187
  5. data/bin/droonga-engine-catalog-generate +12 -12
  6. data/bin/droonga-engine-catalog-modify +4 -4
  7. data/bin/droonga-engine-join +352 -171
  8. data/bin/droonga-engine-set-role +54 -0
  9. data/bin/droonga-engine-unjoin +107 -112
  10. data/droonga-engine.gemspec +3 -3
  11. data/install.sh +55 -36
  12. data/install/centos/functions.sh +2 -2
  13. data/install/debian/functions.sh +2 -2
  14. data/lib/droonga/address.rb +26 -24
  15. data/lib/droonga/buffered_tcp_socket.rb +65 -10
  16. data/lib/droonga/catalog/base.rb +9 -6
  17. data/lib/droonga/catalog/dataset.rb +17 -41
  18. data/lib/droonga/catalog/fetcher.rb +64 -0
  19. data/lib/droonga/catalog/generator.rb +245 -0
  20. data/lib/droonga/catalog/loader.rb +66 -0
  21. data/lib/droonga/{catalog_modifier.rb → catalog/modifier.rb} +11 -18
  22. data/lib/droonga/catalog/replicas_volume.rb +123 -0
  23. data/lib/droonga/catalog/schema.rb +37 -37
  24. data/lib/droonga/catalog/single_volume.rb +11 -3
  25. data/lib/droonga/catalog/slice.rb +10 -6
  26. data/lib/droonga/catalog/{collection_volume.rb → slices_volume.rb} +47 -11
  27. data/lib/droonga/catalog/version1.rb +47 -19
  28. data/lib/droonga/catalog/version2.rb +11 -10
  29. data/lib/droonga/catalog/version2_validator.rb +4 -4
  30. data/lib/droonga/catalog/volume.rb +17 -5
  31. data/lib/droonga/changable.rb +25 -0
  32. data/lib/droonga/cluster.rb +237 -0
  33. data/lib/droonga/collector_runner.rb +4 -0
  34. data/lib/droonga/collectors.rb +2 -1
  35. data/lib/droonga/collectors/recursive_sum.rb +26 -0
  36. data/lib/droonga/command/droonga_engine.rb +404 -127
  37. data/lib/droonga/command/droonga_engine_service.rb +47 -11
  38. data/lib/droonga/command/droonga_engine_worker.rb +21 -1
  39. data/lib/droonga/command/remote_command_base.rb +78 -0
  40. data/lib/droonga/command/serf_event_handler.rb +29 -20
  41. data/lib/droonga/data_absorber_client.rb +222 -0
  42. data/lib/droonga/database_scanner.rb +106 -0
  43. data/lib/droonga/{live_nodes_list_loader.rb → deferrable.rb} +11 -24
  44. data/lib/droonga/differ.rb +58 -0
  45. data/lib/droonga/dispatcher.rb +155 -32
  46. data/lib/droonga/distributed_command_planner.rb +9 -11
  47. data/lib/droonga/engine.rb +83 -78
  48. data/lib/droonga/engine/version.rb +1 -1
  49. data/lib/droonga/engine_node.rb +301 -0
  50. data/lib/droonga/engine_state.rb +62 -40
  51. data/lib/droonga/farm.rb +44 -5
  52. data/lib/droonga/file_observer.rb +16 -12
  53. data/lib/droonga/fluent_message_receiver.rb +98 -29
  54. data/lib/droonga/fluent_message_sender.rb +30 -23
  55. data/lib/droonga/forward_buffer.rb +160 -0
  56. data/lib/droonga/forwarder.rb +73 -40
  57. data/lib/droonga/handler.rb +7 -6
  58. data/lib/droonga/handler_messenger.rb +15 -6
  59. data/lib/droonga/handler_runner.rb +6 -1
  60. data/lib/droonga/internal_fluent_message_receiver.rb +28 -8
  61. data/lib/droonga/job_pusher.rb +10 -7
  62. data/lib/droonga/job_receiver.rb +6 -4
  63. data/lib/droonga/logger.rb +7 -1
  64. data/lib/droonga/node_name.rb +90 -0
  65. data/lib/droonga/node_role.rb +72 -0
  66. data/lib/droonga/path.rb +34 -9
  67. data/lib/droonga/planner.rb +73 -7
  68. data/lib/droonga/plugin/async_command.rb +154 -0
  69. data/lib/droonga/plugins/catalog.rb +1 -0
  70. data/lib/droonga/plugins/crud.rb +22 -6
  71. data/lib/droonga/plugins/dump.rb +66 -135
  72. data/lib/droonga/plugins/groonga/delete.rb +13 -0
  73. data/lib/droonga/plugins/search/distributed_search_planner.rb +4 -4
  74. data/lib/droonga/plugins/system.rb +5 -26
  75. data/lib/droonga/plugins/system/absorb_data.rb +405 -0
  76. data/lib/droonga/plugins/system/statistics.rb +71 -0
  77. data/lib/droonga/plugins/system/status.rb +53 -0
  78. data/lib/droonga/process_control_protocol.rb +3 -1
  79. data/lib/droonga/process_supervisor.rb +32 -15
  80. data/lib/droonga/reducer.rb +69 -0
  81. data/lib/droonga/safe_file_writer.rb +1 -1
  82. data/lib/droonga/serf.rb +207 -276
  83. data/lib/droonga/serf/agent.rb +228 -0
  84. data/lib/droonga/serf/command.rb +94 -0
  85. data/lib/droonga/serf/downloader.rb +120 -0
  86. data/lib/droonga/serf/remote_command.rb +348 -0
  87. data/lib/droonga/serf/tag.rb +56 -0
  88. data/lib/droonga/service_installation.rb +2 -2
  89. data/lib/droonga/session.rb +49 -1
  90. data/lib/droonga/single_step.rb +6 -11
  91. data/lib/droonga/single_step_definition.rb +32 -1
  92. data/lib/droonga/slice.rb +14 -9
  93. data/lib/droonga/supervisor.rb +27 -20
  94. data/lib/droonga/test/stub_handler_messenger.rb +2 -1
  95. data/lib/droonga/timestamp.rb +69 -0
  96. data/lib/droonga/worker_process_agent.rb +33 -15
  97. data/sample/cluster-state.json +8 -0
  98. data/sample/cluster/Rakefile +30 -6
  99. data/test/command/fixture/integer-key-table.jsons +11 -0
  100. data/test/command/fixture/string-key-table.jsons +11 -0
  101. data/test/command/run-test.rb +4 -0
  102. data/test/command/suite/add/error/invalid-integer.expected +3 -3
  103. data/test/command/suite/add/error/invalid-time.expected +3 -3
  104. data/test/command/suite/add/{minimum.expected → key-integer.expected} +0 -0
  105. data/test/command/suite/add/{minimum.test → key-integer.test} +0 -0
  106. data/test/command/suite/add/key-string.expected +6 -0
  107. data/test/command/suite/add/key-string.test +9 -0
  108. data/test/command/suite/add/mismatched-key-type/acceptable/integer-for-string.expected +6 -0
  109. data/test/command/suite/add/mismatched-key-type/acceptable/integer-for-string.test +9 -0
  110. data/test/command/suite/add/mismatched-key-type/acceptable/string-for-integer.expected +6 -0
  111. data/test/command/suite/add/mismatched-key-type/acceptable/string-for-integer.test +9 -0
  112. data/test/command/suite/add/without-values.expected +6 -0
  113. data/test/command/suite/add/without-values.test +11 -0
  114. data/test/command/suite/dump/column/index.expected +33 -1
  115. data/test/command/suite/dump/column/index.test +1 -0
  116. data/test/command/suite/dump/column/scalar.expected +29 -1
  117. data/test/command/suite/dump/column/scalar.test +1 -0
  118. data/test/command/suite/dump/column/vector.expected +29 -1
  119. data/test/command/suite/dump/column/vector.test +1 -0
  120. data/test/command/suite/dump/record/scalar.catalog.json +12 -0
  121. data/test/command/suite/dump/record/scalar.expected +84 -0
  122. data/test/command/suite/dump/record/scalar.test +16 -0
  123. data/test/command/suite/dump/record/vector/reference.expected +83 -1
  124. data/test/command/suite/dump/record/vector/reference.test +1 -0
  125. data/test/command/suite/dump/table/array.expected +27 -1
  126. data/test/command/suite/dump/table/array.test +1 -0
  127. data/test/command/suite/dump/table/double_array_trie.expected +27 -1
  128. data/test/command/suite/dump/table/double_array_trie.test +1 -0
  129. data/test/command/suite/dump/table/hash.expected +27 -1
  130. data/test/command/suite/dump/table/hash.test +1 -0
  131. data/test/command/suite/dump/table/patricia_trie.expected +27 -1
  132. data/test/command/suite/dump/table/patricia_trie.test +1 -0
  133. data/test/command/suite/groonga/delete/{success.expected → key-integer.expected} +0 -0
  134. data/test/command/suite/groonga/delete/key-integer.test +17 -0
  135. data/test/command/suite/groonga/delete/key-string.expected +19 -0
  136. data/test/command/suite/groonga/delete/{success.test → key-string.test} +4 -6
  137. data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/integer-for-string.expected +19 -0
  138. data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/integer-for-string.test +17 -0
  139. data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/string-for-integer.expected +19 -0
  140. data/test/command/suite/groonga/delete/mismatched-type-key/acceptable/string-for-integer.test +17 -0
  141. data/test/command/suite/message/error/missing-dataset.test +1 -0
  142. data/test/command/suite/system/absorb-data/records.catalog.json +58 -0
  143. data/test/command/suite/system/absorb-data/records.expected +32 -0
  144. data/test/command/suite/system/absorb-data/records.test +24 -0
  145. data/test/command/suite/system/statistics/object/count/empty.expected +11 -0
  146. data/test/command/suite/system/statistics/object/count/empty.test +12 -0
  147. data/test/command/suite/system/statistics/object/count/per-volume/empty.catalog.json +36 -0
  148. data/test/command/suite/system/statistics/object/count/per-volume/empty.expected +19 -0
  149. data/test/command/suite/system/statistics/object/count/per-volume/empty.test +12 -0
  150. data/test/command/suite/system/statistics/object/count/per-volume/record.catalog.json +40 -0
  151. data/test/command/suite/system/statistics/object/count/per-volume/record.expected +19 -0
  152. data/test/command/suite/system/statistics/object/count/per-volume/record.test +23 -0
  153. data/test/command/suite/system/statistics/object/count/per-volume/schema.catalog.json +40 -0
  154. data/test/command/suite/system/statistics/object/count/per-volume/schema.expected +19 -0
  155. data/test/command/suite/system/statistics/object/count/per-volume/schema.test +13 -0
  156. data/test/command/suite/system/statistics/object/count/record.catalog.json +12 -0
  157. data/test/command/suite/system/statistics/object/count/record.expected +11 -0
  158. data/test/command/suite/system/statistics/object/count/record.test +23 -0
  159. data/test/command/suite/system/statistics/object/count/schema.catalog.json +12 -0
  160. data/test/command/suite/system/statistics/object/count/schema.expected +11 -0
  161. data/test/command/suite/system/statistics/object/count/schema.test +13 -0
  162. data/test/command/suite/system/status.expected +3 -2
  163. data/test/unit/catalog/test_dataset.rb +4 -1
  164. data/test/unit/{test_catalog_generator.rb → catalog/test_generator.rb} +2 -2
  165. data/test/unit/catalog/test_replicas_volume.rb +79 -0
  166. data/test/unit/catalog/test_single_volume.rb +2 -2
  167. data/test/unit/catalog/test_slice.rb +33 -1
  168. data/test/unit/catalog/{test_collection_volume.rb → test_slices_volume.rb} +72 -11
  169. data/test/unit/catalog/test_version2.rb +3 -0
  170. data/test/unit/helper/distributed_search_planner_helper.rb +2 -2
  171. data/test/unit/plugins/catalog/test_fetch.rb +4 -4
  172. data/test/unit/plugins/crud/test_add.rb +44 -4
  173. data/test/unit/plugins/groonga/test_column_create.rb +4 -4
  174. data/test/unit/plugins/groonga/test_column_list.rb +4 -4
  175. data/test/unit/plugins/groonga/test_column_remove.rb +4 -4
  176. data/test/unit/plugins/groonga/test_column_rename.rb +4 -4
  177. data/test/unit/plugins/groonga/test_delete.rb +73 -10
  178. data/test/unit/plugins/groonga/test_table_create.rb +4 -4
  179. data/test/unit/plugins/groonga/test_table_list.rb +4 -4
  180. data/test/unit/plugins/groonga/test_table_remove.rb +4 -4
  181. data/test/unit/plugins/search/test_handler.rb +4 -4
  182. data/test/unit/plugins/search/test_planner.rb +4 -2
  183. data/test/unit/plugins/system/test_status.rb +31 -15
  184. data/test/unit/plugins/test_watch.rb +16 -16
  185. data/test/unit/test_address.rb +4 -4
  186. metadata +134 -35
  187. data/lib/droonga/catalog/volume_collection.rb +0 -79
  188. data/lib/droonga/catalog_fetcher.rb +0 -53
  189. data/lib/droonga/catalog_generator.rb +0 -243
  190. data/lib/droonga/catalog_loader.rb +0 -56
  191. data/lib/droonga/command/remote.rb +0 -404
  192. data/lib/droonga/data_absorber.rb +0 -264
  193. data/lib/droonga/node_status.rb +0 -71
  194. data/lib/droonga/serf_downloader.rb +0 -115
  195. data/test/unit/catalog/test_volume_collection.rb +0 -78
@@ -19,55 +19,55 @@ module Droonga
19
19
  module Catalog
20
20
  class Schema
21
21
  class ColumnVectorOptions
22
- def initialize(data)
23
- @data = data
22
+ def initialize(raw)
23
+ @raw = raw
24
24
  end
25
25
 
26
26
  def weight
27
- @data["weight"]
27
+ @raw["weight"]
28
28
  end
29
29
  end
30
30
 
31
31
  class ColumnIndexOptions
32
- def initialize(data)
33
- @data = data
32
+ def initialize(raw)
33
+ @raw = raw
34
34
  end
35
35
 
36
36
  def section
37
- @data["section"]
37
+ @raw["section"]
38
38
  end
39
39
 
40
40
  def weight
41
- @data["weight"]
41
+ @raw["weight"]
42
42
  end
43
43
 
44
44
  def position
45
- @data["position"]
45
+ @raw["position"]
46
46
  end
47
47
 
48
48
  def sources
49
- @data["sources"]
49
+ @raw["sources"]
50
50
  end
51
51
  end
52
52
 
53
53
  class Column
54
- attr_reader :table, :name, :data, :vector_options, :index_options
55
- def initialize(table, name, data)
54
+ attr_reader :table, :name, :raw, :vector_options, :index_options
55
+ def initialize(table, name, raw)
56
56
  @table = table
57
57
  @name = name
58
- @data = data
59
- @vector_options = ColumnVectorOptions.new(vector_options_data)
60
- @index_options = ColumnIndexOptions.new(index_options_data)
58
+ @raw = raw
59
+ @vector_options = ColumnVectorOptions.new(raw_vector_options)
60
+ @index_options = ColumnIndexOptions.new(raw_index_options)
61
61
  end
62
62
 
63
63
  def ==(other)
64
64
  self.class == other.class and
65
65
  name == other.name and
66
- data == other.data
66
+ raw == other.raw
67
67
  end
68
68
 
69
69
  def type
70
- @data["type"] || "Scalar"
70
+ @raw["type"] || "Scalar"
71
71
  end
72
72
 
73
73
  def type_symbol
@@ -82,7 +82,7 @@ module Droonga
82
82
  end
83
83
 
84
84
  def value_type
85
- @data["valueType"]
85
+ @raw["valueType"]
86
86
  end
87
87
 
88
88
  def value_type_groonga
@@ -94,35 +94,35 @@ module Droonga
94
94
  end
95
95
 
96
96
  private
97
- def vector_options_data
98
- @data["vectorOptions"] || {}
97
+ def raw_vector_options
98
+ @raw["vectorOptions"] || {}
99
99
  end
100
100
 
101
- def index_options_data
102
- @data["indexOptions"] || {}
101
+ def raw_index_options
102
+ @raw["indexOptions"] || {}
103
103
  end
104
104
  end
105
105
 
106
106
  class Table
107
- attr_reader :name, :columns, :data
108
- def initialize(name, data)
107
+ attr_reader :name, :columns, :raw
108
+ def initialize(name, raw)
109
109
  @name = name
110
- @data = data
110
+ @raw = raw
111
111
  @columns = {}
112
112
 
113
- columns_data.each do |column_name, column_data|
114
- @columns[column_name] = Column.new(name, column_name, column_data)
113
+ raw_columns.each do |column_name, raw_column|
114
+ @columns[column_name] = Column.new(name, column_name, raw_column)
115
115
  end
116
116
  end
117
117
 
118
118
  def ==(other)
119
119
  self.class == other.class and
120
120
  name == other.name and
121
- data == other.data
121
+ raw == other.raw
122
122
  end
123
123
 
124
124
  def type
125
- @data["type"] || "Hash"
125
+ @raw["type"] || "Hash"
126
126
  end
127
127
 
128
128
  def type_symbol
@@ -139,7 +139,7 @@ module Droonga
139
139
  end
140
140
 
141
141
  def key_type
142
- @data["keyType"]
142
+ @raw["keyType"]
143
143
  end
144
144
 
145
145
  def key_type_groonga
@@ -154,26 +154,26 @@ module Droonga
154
154
  end
155
155
 
156
156
  def tokenizer
157
- @data["tokenizer"]
157
+ @raw["tokenizer"]
158
158
  end
159
159
 
160
160
  def normalizer
161
- @data["normalizer"]
161
+ @raw["normalizer"]
162
162
  end
163
163
 
164
164
  private
165
- def columns_data
166
- @data["columns"] || []
165
+ def raw_columns
166
+ @raw["columns"] || []
167
167
  end
168
168
  end
169
169
 
170
170
  attr_reader :tables
171
- def initialize(dataset_name, data)
171
+ def initialize(dataset_name, raw)
172
172
  @dataset_name = dataset_name
173
- @data = data || []
173
+ @raw = raw || []
174
174
  @tables = {}
175
- @data.each do |table_name, table_data|
176
- @tables[table_name] = Table.new(table_name, table_data)
175
+ @raw.each do |table_name, raw_table|
176
+ @tables[table_name] = Table.new(table_name, raw_table)
177
177
  end
178
178
  end
179
179
 
@@ -19,9 +19,9 @@ module Droonga
19
19
  module Catalog
20
20
  class SingleVolume
21
21
  attr_reader :address
22
- def initialize(data)
23
- @data = data
24
- @address = Address.parse(@data["address"])
22
+ def initialize(raw)
23
+ @raw = raw
24
+ @address = Address.parse(@raw["address"])
25
25
  end
26
26
 
27
27
  def node
@@ -31,6 +31,14 @@ module Droonga
31
31
  def all_nodes
32
32
  @all_nodes ||= [node]
33
33
  end
34
+
35
+ def compute_routes(message, active_nodes)
36
+ [address.to_s]
37
+ end
38
+
39
+ def sliced?
40
+ false
41
+ end
34
42
  end
35
43
  end
36
44
  end
@@ -16,30 +16,34 @@
16
16
  module Droonga
17
17
  module Catalog
18
18
  class Slice
19
- def initialize(dataset, data)
19
+ def initialize(dataset, raw)
20
20
  @dataset = dataset
21
- @data = data
21
+ @raw = raw
22
22
  end
23
23
 
24
24
  def weight
25
- @data["weight"] || 1
25
+ @raw["weight"] || 1
26
26
  end
27
27
 
28
28
  def label
29
- @data["label"]
29
+ @raw["label"]
30
30
  end
31
31
 
32
32
  def boundary
33
- @data["boundary"]
33
+ @raw["boundary"]
34
34
  end
35
35
 
36
36
  def volume
37
- @volume ||= Volume.create(@dataset, @data["volume"])
37
+ @volume ||= Catalog::Volume.create(@dataset, @raw["volume"])
38
38
  end
39
39
 
40
40
  def all_nodes
41
41
  @all_nodes ||= volume.all_nodes
42
42
  end
43
+
44
+ def compute_routes(message, active_nodes)
45
+ volume.compute_routes(message, active_nodes)
46
+ end
43
47
  end
44
48
  end
45
49
  end
@@ -20,29 +20,35 @@ require "droonga/catalog/slice"
20
20
 
21
21
  module Droonga
22
22
  module Catalog
23
- class CollectionVolume
24
- def initialize(dataset, data)
23
+ class SlicesVolume
24
+ def initialize(dataset, raw)
25
25
  @dataset = dataset
26
- @data = data
26
+ @raw = raw
27
27
  compute_continuum if ratio_scaled_slicer?
28
28
  end
29
29
 
30
30
  def dimension
31
- @data["dimension"] || "_key"
31
+ @raw["dimension"] || "_key"
32
32
  end
33
33
 
34
34
  def slicer
35
- @data["slicer"] || "hash"
35
+ @raw["slicer"] || "hash"
36
36
  end
37
37
 
38
38
  def slices
39
- @slices ||= @data["slices"].collect do |raw_slice|
40
- Slice.new(@dataset, raw_slice)
41
- end
39
+ @slices ||= create_slices
42
40
  end
43
41
 
44
- def select_slices(range=0..-1)
45
- slices.sort_by(&:label)[range]
42
+ def select_slices(how=:all, range=0..-1)
43
+ selected = slices.sort_by(&:label)[range]
44
+ case how
45
+ when :random
46
+ [selected.sample]
47
+ when :all
48
+ selected
49
+ else
50
+ selected
51
+ end
46
52
  end
47
53
 
48
54
  def choose_slice(record)
@@ -73,6 +79,30 @@ module Droonga
73
79
  @all_nodes ||= collect_all_nodes
74
80
  end
75
81
 
82
+ def compute_routes(message, active_nodes)
83
+ routes = []
84
+ slices = []
85
+ case message["type"]
86
+ when "broadcast"
87
+ slices = select_slices(message["slice"].to_sym)
88
+ when "scatter"
89
+ record = message["record"]
90
+ if record
91
+ slices = [choose_slice(record)]
92
+ else
93
+ slices = select_slices(message["slice"].to_sym)
94
+ end
95
+ end
96
+ slices.each do |slice|
97
+ routes.concat(slice.compute_routes(message, active_nodes))
98
+ end
99
+ routes
100
+ end
101
+
102
+ def sliced?
103
+ slices.size > 1
104
+ end
105
+
76
106
  private
77
107
  def compute_continuum
78
108
  total_weight = compute_total_weight
@@ -106,10 +136,16 @@ module Droonga
106
136
  end
107
137
  end
108
138
 
139
+ def create_slices
140
+ @raw["slices"].collect do |raw_slice|
141
+ Slice.new(@dataset, raw_slice)
142
+ end
143
+ end
144
+
109
145
  def collect_all_nodes
110
146
  nodes = []
111
147
  slices.each do |slice|
112
- nodes += slice.all_nodes
148
+ nodes.concat(slice.all_nodes)
113
149
  end
114
150
  nodes.uniq.sort
115
151
  end
@@ -23,7 +23,7 @@ require "droonga/catalog/dataset"
23
23
  module Droonga
24
24
  module Catalog
25
25
  class Version1 < Base
26
- def initialize(data, path)
26
+ def initialize(raw, path)
27
27
  super
28
28
  @errors = []
29
29
 
@@ -42,10 +42,10 @@ module Droonga
42
42
  end
43
43
 
44
44
  def get_partitions(name)
45
- device = @data["farms"][name]["device"]
45
+ device = @raw["farms"][name]["device"]
46
46
  pattern = Regexp.new("^#{name}\.")
47
47
  results = {}
48
- @data["datasets"].each do |dataset_name, dataset_data|
48
+ @raw["datasets"].each do |dataset_name, dataset_data|
49
49
  dataset = Dataset.new(dataset_name, dataset_data)
50
50
  workers = dataset["workers"]
51
51
  plugins = dataset["plugins"]
@@ -79,7 +79,7 @@ module Droonga
79
79
  private
80
80
  def prepare_data
81
81
  @datasets = {}
82
- @data["datasets"].each do |name, dataset|
82
+ @raw["datasets"].each do |name, dataset|
83
83
  @datasets[name] = Dataset.new(name, dataset)
84
84
  number_of_partitions = dataset["number_of_partitions"]
85
85
  next if number_of_partitions < 2
@@ -94,7 +94,7 @@ module Droonga
94
94
  end
95
95
  dataset["continuum"] = continuum.sort do |a, b| a[0] - b[0]; end
96
96
  end
97
- @options = @data["options"] || {}
97
+ @options = @raw["options"] || {}
98
98
  end
99
99
 
100
100
  def compute_total_weight(dataset)
@@ -104,7 +104,7 @@ module Droonga
104
104
  end
105
105
 
106
106
  def collect_all_nodes
107
- @data["zones"].sort
107
+ @raw["zones"].sort
108
108
  end
109
109
 
110
110
  def validate
@@ -190,13 +190,13 @@ module Droonga
190
190
  end
191
191
 
192
192
  def validate_effective_date
193
- date = @data["effective_date"]
193
+ date = @raw["effective_date"]
194
194
  validate_required_parameter(date, "effective_date")
195
195
  validate_valid_datetime(date, "effective_date")
196
196
  end
197
197
 
198
198
  def validate_farms
199
- farms = @data["farms"]
199
+ farms = @raw["farms"]
200
200
 
201
201
  validate_required_parameter(farms, "farms")
202
202
  validate_parameter_type(Hash, farms, "farms")
@@ -214,7 +214,7 @@ module Droonga
214
214
  end
215
215
 
216
216
  def validate_zones
217
- zones = @data["zones"]
217
+ zones = @raw["zones"]
218
218
 
219
219
  validate_required_parameter(zones, "zones")
220
220
  validate_parameter_type(Array, zones, "zones")
@@ -236,7 +236,7 @@ module Droonga
236
236
  end
237
237
 
238
238
  def validate_datasets
239
- datasets = @data["datasets"]
239
+ datasets = @raw["datasets"]
240
240
 
241
241
  validate_required_parameter(datasets, "datasets")
242
242
  validate_parameter_type(Hash, datasets, "datasets")
@@ -328,11 +328,11 @@ module Droonga
328
328
  end
329
329
 
330
330
  def validate_zone_relations
331
- return unless @data["zones"].is_a?(Array)
332
- return unless @data["farms"].is_a?(Hash)
331
+ return unless @raw["zones"].is_a?(Array)
332
+ return unless @raw["farms"].is_a?(Hash)
333
333
 
334
- farms = @data["farms"]
335
- zones = @data["zones"]
334
+ farms = @raw["farms"]
335
+ zones = @raw["zones"]
336
336
 
337
337
  all_farms = farms.keys
338
338
  all_zones = zones.flatten
@@ -351,14 +351,14 @@ module Droonga
351
351
  end
352
352
 
353
353
  def validate_database_relations
354
- return unless @data["farms"]
354
+ return unless @raw["farms"]
355
355
 
356
- farm_names = @data["farms"].keys.collect do |name|
356
+ farm_names = @raw["farms"].keys.collect do |name|
357
357
  Regexp.escape(name)
358
358
  end
359
359
  valid_farms_matcher = Regexp.new("^(#{farm_names.join("|")})\.")
360
360
 
361
- @data["datasets"].each do |dataset_name, dataset|
361
+ @raw["datasets"].each do |dataset_name, dataset|
362
362
  ring = dataset["ring"]
363
363
  next if ring.nil? or !ring.is_a?(Hash)
364
364
  ring.each do |ring_key, part|
@@ -389,7 +389,7 @@ module Droonga
389
389
  end
390
390
 
391
391
  class Dataset < Catalog::Dataset
392
- def compute_routes(args, live_nodes=nil)
392
+ def compute_routes(args, active_nodes=nil)
393
393
  routes = []
394
394
  case args["type"]
395
395
  when "broadcast"
@@ -397,7 +397,13 @@ module Droonga
397
397
  select_range_and_replicas(partition, args, routes)
398
398
  end
399
399
  when "scatter"
400
- name = get_partition(args["record"]["_key"])
400
+ record = args["record"]
401
+ if record
402
+ key = record["_key"]
403
+ else
404
+ key = nil
405
+ end
406
+ name = get_partition(key)
401
407
  partition = self["ring"][name]
402
408
  select_range_and_replicas(partition, args, routes)
403
409
  end
@@ -407,6 +413,8 @@ module Droonga
407
413
  def get_partition(key)
408
414
  continuum = self["continuum"]
409
415
  return self["ring"].keys[0] unless continuum
416
+ return continuum.sample[1] unless key
417
+ key = key.to_s unless key.is_a?(String)
410
418
  hash = Zlib.crc32(key)
411
419
  min = 0
412
420
  max = continuum.size - 1
@@ -436,6 +444,26 @@ module Droonga
436
444
  end
437
445
  end
438
446
  end
447
+
448
+ def all_nodes
449
+ @all_nodes ||= collect_all_nodes
450
+ end
451
+
452
+ def sliced?
453
+ self["ring"].keys.size > 1
454
+ end
455
+
456
+ private
457
+ def collect_all_nodes
458
+ nodes = []
459
+ self["ring"].each do |ring_key, part|
460
+ part["partitions"].each do |partition|
461
+ partition =~ /\A([^:]+:[0-9]+\/[^\.]+)/
462
+ nodes << $1
463
+ end
464
+ end
465
+ nodes.sort.uniq
466
+ end
439
467
  end
440
468
  end
441
469
  end