droonga-engine 1.0.9 → 1.1.0

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