fluent-plugin-droonga 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +1 -1
- data/Gemfile +1 -1
- data/fluent-plugin-droonga.gemspec +1 -1
- data/lib/droonga/catalog/collection_volume.rb +97 -0
- data/lib/droonga/catalog/dataset.rb +28 -1
- data/lib/droonga/catalog/errors.rb +28 -9
- data/lib/droonga/catalog/schema.rb +23 -2
- data/lib/droonga/catalog/single_volume.rb +28 -0
- data/lib/droonga/catalog/slice.rb +43 -0
- data/lib/droonga/catalog/version1.rb +3 -3
- data/lib/droonga/catalog/version2.rb +17 -81
- data/lib/droonga/catalog/version2_validator.rb +63 -0
- data/lib/droonga/catalog/volume.rb +33 -0
- data/lib/droonga/catalog/volume_collection.rb +56 -0
- data/lib/droonga/catalog_observer.rb +7 -19
- data/lib/droonga/collectors.rb +1 -1
- data/lib/droonga/collectors/{add.rb → or.rb} +1 -1
- data/lib/droonga/dispatcher.rb +24 -18
- data/lib/droonga/distributed_command_planner.rb +7 -11
- data/lib/droonga/distributor.rb +29 -17
- data/lib/droonga/event_loop.rb +2 -11
- data/lib/droonga/fluent_message_sender.rb +51 -5
- data/lib/droonga/handler_runner.rb +1 -1
- data/lib/droonga/job_protocol.rb +20 -0
- data/lib/droonga/job_pusher.rb +178 -0
- data/lib/droonga/{message_receiver.rb → job_receiver.rb} +13 -6
- data/lib/droonga/message_matcher.rb +18 -15
- data/lib/droonga/planner.rb +2 -3
- data/lib/droonga/plugins/crud.rb +1 -1
- data/lib/droonga/plugins/groonga/column_create.rb +4 -1
- data/lib/droonga/plugins/groonga/table_create.rb +1 -1
- data/lib/droonga/plugins/groonga/table_remove.rb +1 -1
- data/lib/droonga/plugins/search/distributed_search_planner.rb +9 -0
- data/lib/droonga/processor.rb +3 -3
- data/lib/droonga/reducer.rb +15 -12
- data/lib/droonga/searcher.rb +49 -4
- data/lib/droonga/server.rb +2 -0
- data/lib/droonga/single_step.rb +22 -7
- data/lib/droonga/slice.rb +7 -7
- data/lib/droonga/step_runner.rb +3 -2
- data/lib/droonga/worker.rb +10 -8
- data/test/command/suite/add/dimension/column.catalog.json +27 -0
- data/test/command/suite/add/dimension/column.expected +57 -0
- data/test/command/suite/add/dimension/column.test +51 -0
- data/test/command/suite/search/adjusters/multiple.catalog.json +38 -0
- data/test/command/suite/search/adjusters/multiple.expected +23 -0
- data/test/command/suite/search/adjusters/multiple.test +75 -0
- data/test/command/suite/search/adjusters/one.catalog.json +38 -0
- data/test/command/suite/search/adjusters/one.expected +23 -0
- data/test/command/suite/search/adjusters/one.test +66 -0
- data/test/command/suite/search/attributes/array.test +0 -2
- data/test/command/suite/search/attributes/hash.test +0 -2
- data/test/command/suite/search/complex.test +0 -2
- data/test/command/suite/search/condition/nested.test +0 -2
- data/test/command/suite/search/condition/query.test +0 -2
- data/test/command/suite/search/condition/script.test +0 -2
- data/test/command/suite/search/group/string.test +0 -4
- data/test/command/suite/search/group/subrecord/with-sort.catalog.json +33 -0
- data/test/command/suite/search/group/subrecord/with-sort.expected +34 -0
- data/test/command/suite/search/group/subrecord/with-sort.test +81 -0
- data/test/command/suite/search/multiple/chained.test +0 -4
- data/test/command/suite/search/multiple/parallel.test +0 -4
- data/test/command/suite/search/range/only-output.test +0 -2
- data/test/command/suite/search/range/only-sort.test +0 -2
- data/test/command/suite/search/range/sort-and-output.test +0 -2
- data/test/command/suite/search/range/too-large-output-offset.test +0 -2
- data/test/command/suite/search/range/too-large-sort-offset.test +0 -2
- data/test/command/suite/search/response/elapsed_time.catalog.json +13 -0
- data/test/command/suite/search/response/elapsed_time.expected +15 -0
- data/test/command/suite/search/response/elapsed_time.test +26 -0
- data/test/command/suite/search/response/records/value/time.test +0 -2
- data/test/command/suite/search/simple.test +0 -2
- data/test/command/suite/search/sort/default-offset-limit.test +0 -2
- data/test/command/suite/search/sort/invisible-column.test +0 -2
- data/test/unit/catalog/test_collection_volume.rb +103 -0
- data/test/unit/catalog/test_dataset.rb +69 -8
- data/test/unit/catalog/test_schema.rb +63 -23
- data/test/unit/catalog/test_single_volume.rb +31 -0
- data/test/unit/catalog/test_slice.rb +92 -0
- data/test/unit/catalog/test_version1.rb +1 -1
- data/test/unit/catalog/test_version2.rb +1 -32
- data/test/unit/catalog/test_version2_validator.rb +66 -0
- data/test/unit/catalog/test_volume_collection.rb +50 -0
- data/test/unit/plugins/groonga/test_column_create.rb +4 -1
- data/test/unit/plugins/groonga/test_table_create.rb +1 -1
- data/test/unit/test_message_matcher.rb +15 -15
- data/test/unit/test_watch_schema.rb +1 -1
- metadata +107 -94
- checksums.yaml +0 -7
- data/lib/droonga/message_pusher.rb +0 -64
@@ -69,6 +69,9 @@ module Droonga
|
|
69
69
|
options[:type] = :scalar
|
70
70
|
elsif @command.column_vector?
|
71
71
|
options[:type] = :vector
|
72
|
+
if @command.with_weight?
|
73
|
+
options[:with_weight] = true
|
74
|
+
end
|
72
75
|
end
|
73
76
|
options
|
74
77
|
end
|
@@ -120,7 +123,7 @@ module Droonga
|
|
120
123
|
step.name = "column_create"
|
121
124
|
step.write = true
|
122
125
|
step.handler = Handler
|
123
|
-
step.collector = Collectors::
|
126
|
+
step.collector = Collectors::Or
|
124
127
|
end
|
125
128
|
end
|
126
129
|
end
|
@@ -122,6 +122,7 @@ module Droonga
|
|
122
122
|
|
123
123
|
calculate_offset_and_limit!
|
124
124
|
build_count_mapper_and_reducer!
|
125
|
+
build_elapsed_time_mapper_and_reducer!
|
125
126
|
build_records_mapper_and_reducer!
|
126
127
|
end
|
127
128
|
|
@@ -256,6 +257,14 @@ module Droonga
|
|
256
257
|
end
|
257
258
|
end
|
258
259
|
|
260
|
+
def build_elapsed_time_mapper_and_reducer!
|
261
|
+
return unless @output["elements"].include?("elapsedTime")
|
262
|
+
|
263
|
+
@reducers["elapsedTime"] = {
|
264
|
+
"type" => "sum",
|
265
|
+
}
|
266
|
+
end
|
267
|
+
|
259
268
|
def build_records_mapper_and_reducer!
|
260
269
|
# Skip reducing phase for a result with no record output.
|
261
270
|
return if !@output["elements"].include?("records") || @records_limit.zero?
|
data/lib/droonga/processor.rb
CHANGED
@@ -20,9 +20,9 @@ module Droonga
|
|
20
20
|
class Processor
|
21
21
|
include Loggable
|
22
22
|
|
23
|
-
def initialize(loop,
|
23
|
+
def initialize(loop, job_pusher, options={})
|
24
24
|
@loop = loop
|
25
|
-
@
|
25
|
+
@job_pusher = job_pusher
|
26
26
|
@options = options
|
27
27
|
@n_workers = @options[:n_workers] || 0
|
28
28
|
end
|
@@ -47,7 +47,7 @@ module Droonga
|
|
47
47
|
if @n_workers.zero? or synchronous
|
48
48
|
@handler_runner.process(message)
|
49
49
|
else
|
50
|
-
@
|
50
|
+
@job_pusher.push(message)
|
51
51
|
end
|
52
52
|
else
|
53
53
|
logger.trace("process: ignore #{type}")
|
data/lib/droonga/reducer.rb
CHANGED
@@ -134,25 +134,28 @@ module Droonga
|
|
134
134
|
base_items, unified_items = unified_items, base_items
|
135
135
|
end
|
136
136
|
|
137
|
-
|
137
|
+
unified_key_map = {}
|
138
|
+
unified_items.each do |unified_item|
|
139
|
+
unified_key_map[unified_item[key_column_index]] = unified_item
|
140
|
+
end
|
138
141
|
|
142
|
+
unified = false
|
139
143
|
base_items.reject! do |base_item|
|
140
144
|
key = base_item[key_column_index]
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
147
|
-
rest_unified_items -= [unified_item]
|
148
|
-
true
|
149
|
-
else
|
150
|
-
false
|
145
|
+
unified_item = unified_key_map[key]
|
146
|
+
if unified_item
|
147
|
+
base_item.each_with_index do |value, column_index|
|
148
|
+
next if column_index == key_column_index
|
149
|
+
unified_item[column_index] += value
|
151
150
|
end
|
151
|
+
unified = true
|
152
|
+
true
|
153
|
+
else
|
154
|
+
false
|
152
155
|
end
|
153
156
|
end
|
154
157
|
|
155
|
-
|
158
|
+
if unified
|
156
159
|
unified_items.sort! do |a, b|
|
157
160
|
if compare(a, b, options[:operators])
|
158
161
|
-1
|
data/lib/droonga/searcher.rb
CHANGED
@@ -61,14 +61,26 @@ module Droonga
|
|
61
61
|
def search(queries)
|
62
62
|
outputs = nil
|
63
63
|
logger.trace("search: start", :queries => queries)
|
64
|
-
|
65
|
-
|
64
|
+
# TODO: THIS IS JUST A WORKAROUND! We should remove it ASAP!
|
65
|
+
disable_gc do
|
66
|
+
@context.push_memory_pool do
|
67
|
+
outputs = process_queries(queries)
|
68
|
+
end
|
66
69
|
end
|
67
70
|
logger.trace("search: done")
|
68
71
|
return outputs
|
69
72
|
end
|
70
73
|
|
71
74
|
private
|
75
|
+
def disable_gc
|
76
|
+
GC.disable
|
77
|
+
begin
|
78
|
+
yield
|
79
|
+
ensure
|
80
|
+
GC.enable
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
72
84
|
def process_queries(queries)
|
73
85
|
logger.trace("process_queries: start")
|
74
86
|
if queries.nil? or queries.empty?
|
@@ -302,7 +314,12 @@ module Droonga
|
|
302
314
|
@records = @request.source
|
303
315
|
|
304
316
|
condition = @request.query["condition"]
|
305
|
-
|
317
|
+
if condition
|
318
|
+
apply_condition!(condition)
|
319
|
+
|
320
|
+
adjusters = @request.query["adjusters"]
|
321
|
+
apply_adjusters!(adjusters) if adjusters
|
322
|
+
end
|
306
323
|
|
307
324
|
group_by = @request.query["groupBy"]
|
308
325
|
apply_group_by!(group_by) if group_by
|
@@ -328,6 +345,29 @@ module Droonga
|
|
328
345
|
@result.condition = expression
|
329
346
|
end
|
330
347
|
|
348
|
+
def apply_adjusters!(adjusters)
|
349
|
+
logger.trace("search_query: adjusters: start")
|
350
|
+
adjusters.each do |adjuster|
|
351
|
+
column_name = adjuster["column"]
|
352
|
+
value = adjuster["value"]
|
353
|
+
factor = adjuster["factor"] || 1
|
354
|
+
logger.trace("search_query: adjusters: adjuster: start",
|
355
|
+
:column_name => column_name,
|
356
|
+
:value => value,
|
357
|
+
:factor => factor)
|
358
|
+
column = @request.source.column(column_name)
|
359
|
+
index, = column.indexes(:match)
|
360
|
+
# TODO: add index.nil? check
|
361
|
+
# TODO: add value.nil? check
|
362
|
+
index.search(value,
|
363
|
+
:result => @records,
|
364
|
+
:operator => :adjust,
|
365
|
+
:weight => factor)
|
366
|
+
logger.trace("search_query: adjusters: adjuster: done")
|
367
|
+
end
|
368
|
+
logger.trace("search_query: adjusters: done")
|
369
|
+
end
|
370
|
+
|
331
371
|
def apply_group_by!(group_by)
|
332
372
|
logger.trace("search_query: group: start",
|
333
373
|
:by => group_by)
|
@@ -449,7 +489,12 @@ module Droonga
|
|
449
489
|
module RecordsFormattable
|
450
490
|
def record_value(record, attribute)
|
451
491
|
if attribute[:source] == "_subrecs"
|
452
|
-
record.
|
492
|
+
if record.table.is_a?(Groonga::Array)
|
493
|
+
target_record = record.value
|
494
|
+
else
|
495
|
+
target_record = record
|
496
|
+
end
|
497
|
+
target_record.sub_records.collect do |sub_record|
|
453
498
|
sub_attributes = attribute[:attributes]
|
454
499
|
format_record(sub_attributes, sub_record)
|
455
500
|
end
|
data/lib/droonga/server.rb
CHANGED
data/lib/droonga/single_step.rb
CHANGED
@@ -18,7 +18,8 @@ require "droonga/collectors"
|
|
18
18
|
|
19
19
|
module Droonga
|
20
20
|
class SingleStep
|
21
|
-
def initialize(definition)
|
21
|
+
def initialize(dataset, definition)
|
22
|
+
@dataset = dataset
|
22
23
|
@definition = definition
|
23
24
|
end
|
24
25
|
|
@@ -40,14 +41,28 @@ module Droonga
|
|
40
41
|
reduce_key => collector_class.operator,
|
41
42
|
}
|
42
43
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
|
45
|
+
body = message["body"]
|
46
|
+
fact_input = find_fact_input(@definition.inputs, @dataset.fact, body)
|
47
|
+
if fact_input
|
48
|
+
record = body[fact_input[:filter]]
|
49
|
+
planner.send(:scatter, message, record, options)
|
46
50
|
else
|
47
|
-
|
48
|
-
|
49
|
-
|
51
|
+
planner.send(:broadcast, message, options)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_fact_input(inputs, fact, body)
|
56
|
+
inputs.each do |key, input|
|
57
|
+
if input[:type] == :table
|
58
|
+
# for backward compatibility. We can remove the following code
|
59
|
+
# when all our catalog.json specify "fact" parameter.
|
60
|
+
return input if fact.nil?
|
61
|
+
|
62
|
+
return input if body[key] == fact
|
63
|
+
end
|
50
64
|
end
|
65
|
+
nil
|
51
66
|
end
|
52
67
|
end
|
53
68
|
end
|
data/lib/droonga/slice.rb
CHANGED
@@ -19,7 +19,7 @@ require "droonga/loggable"
|
|
19
19
|
require "droonga/server"
|
20
20
|
require "droonga/worker"
|
21
21
|
require "droonga/event_loop"
|
22
|
-
require "droonga/
|
22
|
+
require "droonga/job_pusher"
|
23
23
|
require "droonga/processor"
|
24
24
|
|
25
25
|
module Droonga
|
@@ -30,23 +30,22 @@ module Droonga
|
|
30
30
|
@options = options
|
31
31
|
@n_workers = @options[:n_workers] || 0
|
32
32
|
@loop = loop
|
33
|
-
@
|
34
|
-
@processor = Processor.new(@loop, @
|
33
|
+
@job_pusher = JobPusher.new(@loop, @options[:database])
|
34
|
+
@processor = Processor.new(@loop, @job_pusher, @options)
|
35
35
|
@supervisor = nil
|
36
36
|
end
|
37
37
|
|
38
38
|
def start
|
39
39
|
ensure_database
|
40
40
|
@processor.start
|
41
|
-
|
42
|
-
@message_pusher.start(base_path)
|
41
|
+
@job_pusher.start
|
43
42
|
start_supervisor if @n_workers > 0
|
44
43
|
end
|
45
44
|
|
46
45
|
def shutdown
|
47
46
|
logger.trace("shutdown: start")
|
48
47
|
shutdown_supervisor if @supervisor
|
49
|
-
@
|
48
|
+
@job_pusher.shutdown
|
50
49
|
@processor.shutdown
|
51
50
|
logger.trace("shutdown: done")
|
52
51
|
end
|
@@ -84,7 +83,8 @@ module Droonga
|
|
84
83
|
:log_level => logger.level,
|
85
84
|
:server_process_name => "Server[#{@options[:database]}] #$0",
|
86
85
|
:worker_process_name => "Worker[#{@options[:database]}] #$0",
|
87
|
-
:
|
86
|
+
:job_receive_socket_path => @job_pusher.socket_path,
|
87
|
+
:job_pusher => @job_pusher,
|
88
88
|
}
|
89
89
|
@options.merge(force_options)
|
90
90
|
end
|
data/lib/droonga/step_runner.rb
CHANGED
@@ -21,7 +21,8 @@ module Droonga
|
|
21
21
|
class StepRunner
|
22
22
|
include Loggable
|
23
23
|
|
24
|
-
def initialize(plugins)
|
24
|
+
def initialize(dataset, plugins)
|
25
|
+
@dataset = dataset
|
25
26
|
@definitions = {}
|
26
27
|
plugins.each do |name|
|
27
28
|
plugin = Plugin.registry[name]
|
@@ -43,7 +44,7 @@ module Droonga
|
|
43
44
|
if definition.nil?
|
44
45
|
raise UnsupportedMessageError.new(:planner, message)
|
45
46
|
end
|
46
|
-
step = SingleStep.new(definition)
|
47
|
+
step = SingleStep.new(@dataset, definition)
|
47
48
|
plan = step.plan(message)
|
48
49
|
logger.trace("plan: done",
|
49
50
|
:dataset => message["dataset"],
|
data/lib/droonga/worker.rb
CHANGED
@@ -15,16 +15,17 @@
|
|
15
15
|
|
16
16
|
require "droonga/event_loop"
|
17
17
|
require "droonga/handler_runner"
|
18
|
-
require "droonga/
|
18
|
+
require "droonga/job_receiver"
|
19
19
|
|
20
20
|
module Droonga
|
21
21
|
module Worker
|
22
22
|
def initialize
|
23
|
-
@
|
23
|
+
@raw_loop = Coolio::Loop.new
|
24
|
+
@loop = EventLoop.new(@raw_loop)
|
24
25
|
@handler_runner = HandlerRunner.new(@loop,
|
25
26
|
config.merge(:dispatcher => nil))
|
26
|
-
|
27
|
-
@
|
27
|
+
receive_socket_path = config[:job_receive_socket_path]
|
28
|
+
@job_receiver = JobReceiver.new(@loop, receive_socket_path) do |message|
|
28
29
|
process(message)
|
29
30
|
end
|
30
31
|
end
|
@@ -32,16 +33,17 @@ module Droonga
|
|
32
33
|
def run
|
33
34
|
Droonga.logger.trace("#{log_tag}: run: start")
|
34
35
|
@handler_runner.start
|
35
|
-
@
|
36
|
-
@
|
36
|
+
@job_receiver.start
|
37
|
+
@raw_loop.run
|
37
38
|
@handler_runner.shutdown
|
38
39
|
Droonga.logger.trace("#{log_tag}: run: done")
|
39
40
|
end
|
40
41
|
|
41
42
|
def stop
|
42
43
|
Droonga.logger.trace("#{log_tag}: stop: start")
|
43
|
-
@
|
44
|
-
@
|
44
|
+
@job_receiver.shutdown
|
45
|
+
@raw_loop.stop
|
46
|
+
@loop.break_current_loop
|
45
47
|
Droonga.logger.trace("#{log_tag}: stop: done")
|
46
48
|
end
|
47
49
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
{
|
2
|
+
"datasets": {
|
3
|
+
"Droonga": {
|
4
|
+
"schema": {
|
5
|
+
"Products": {
|
6
|
+
"type": "Hash",
|
7
|
+
"keyType": "ShortText",
|
8
|
+
"columns": {
|
9
|
+
"category": {
|
10
|
+
"type": "Scalar",
|
11
|
+
"valueType": "ShortText"
|
12
|
+
}
|
13
|
+
}
|
14
|
+
}
|
15
|
+
},
|
16
|
+
"replicas": [
|
17
|
+
{
|
18
|
+
"dimension": "category"
|
19
|
+
},
|
20
|
+
{
|
21
|
+
"dimension": "category"
|
22
|
+
}
|
23
|
+
]
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
[
|
2
|
+
"droonga.message",
|
3
|
+
0,
|
4
|
+
{
|
5
|
+
"inReplyTo": "request-id",
|
6
|
+
"statusCode": 200,
|
7
|
+
"type": "add.result",
|
8
|
+
"body": true
|
9
|
+
}
|
10
|
+
]
|
11
|
+
[
|
12
|
+
"droonga.message",
|
13
|
+
0,
|
14
|
+
{
|
15
|
+
"inReplyTo": "request-id",
|
16
|
+
"statusCode": 200,
|
17
|
+
"type": "add.result",
|
18
|
+
"body": true
|
19
|
+
}
|
20
|
+
]
|
21
|
+
[
|
22
|
+
"droonga.message",
|
23
|
+
0,
|
24
|
+
{
|
25
|
+
"inReplyTo": "request-id",
|
26
|
+
"statusCode": 200,
|
27
|
+
"type": "add.result",
|
28
|
+
"body": true
|
29
|
+
}
|
30
|
+
]
|
31
|
+
[
|
32
|
+
"droonga.message",
|
33
|
+
0,
|
34
|
+
{
|
35
|
+
"inReplyTo": "request-id",
|
36
|
+
"statusCode": 200,
|
37
|
+
"type": "search.result",
|
38
|
+
"body": {
|
39
|
+
"products": {
|
40
|
+
"records": [
|
41
|
+
[
|
42
|
+
"Groonga",
|
43
|
+
"groonga"
|
44
|
+
],
|
45
|
+
[
|
46
|
+
"Rroonga",
|
47
|
+
"groonga"
|
48
|
+
],
|
49
|
+
[
|
50
|
+
"Ruby",
|
51
|
+
"ruby"
|
52
|
+
]
|
53
|
+
]
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
]
|