Navigation Menu

Skip to content

Commit

Permalink
sharding: extract common code to RangeExpressionBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
kou committed Apr 2, 2015
1 parent 2c93dfe commit 3e01aac
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 154 deletions.
1 change: 1 addition & 0 deletions plugins/sharding.rb
@@ -1,3 +1,4 @@
require "sharding/range_expression_builder"
require "sharding/logical_enumerator"
require "sharding/logical_count"
require "sharding/logical_range_filter"
106 changes: 13 additions & 93 deletions plugins/sharding/logical_count.rb
Expand Up @@ -32,77 +32,31 @@ def count_n_records(table, filter,
cover_type = target_range.cover_type(shard_range)
return 0 if cover_type == :none

expression_builder = RangeExpressionBuilder.new(shard_key,
target_range,
filter)
if cover_type == :all
if filter.nil?
return table.size
else
return filtered_count_n_records(table, filter)
end
end

use_range_index = false
range_index = nil
if filter.nil?
index_info = shard_key.find_index(Operator::LESS)
if index_info
range_index = index_info.index
use_range_index = true
return filtered_count_n_records(table, filter) do |expression|
expression_builder.build_all(expression)
end
end
end

case cover_type
when :partial_min
if use_range_index
count_n_records_in_range(range_index,
target_range.min, target_range.min_border,
nil, nil)
else
filtered_count_n_records(table, filter) do |expression|
expression.append_object(shard_key, Operator::PUSH, 1)
expression.append_operator(Operator::GET_VALUE, 1)
expression.append_constant(target_range.min, Operator::PUSH, 1)
if target_range.min_border == :include
expression.append_operator(Operator::GREATER_EQUAL, 2)
else
expression.append_operator(Operator::GREATER, 2)
end
end
filtered_count_n_records(table, filter) do |expression|
expression_builder.build_partial_min(expression)
end
when :partial_max
if use_range_index
count_n_records_in_range(range_index,
nil, nil,
target_range.max, target_range.max_border)
else
filtered_count_n_records(table, filter) do |expression|
expression.append_object(shard_key, Operator::PUSH, 1)
expression.append_operator(Operator::GET_VALUE, 1)
expression.append_constant(target_range.max, Operator::PUSH, 1)
if target_range.max_border == :include
expression.append_operator(Operator::LESS_EQUAL, 2)
else
expression.append_operator(Operator::LESS, 2)
end
end
filtered_count_n_records(table, filter) do |expression|
expression_builder.build_partial_max(expression)
end
when :partial_min_and_max
if use_range_index
count_n_records_in_range(range_index,
target_range.min, target_range.min_border,
target_range.max, target_range.max_border)
else
filtered_count_n_records(table, filter) do |expression|
expression.append_object(context["between"], Operator::PUSH, 1)
expression.append_object(shard_key, Operator::PUSH, 1)
expression.append_operator(Operator::GET_VALUE, 1)
expression.append_constant(target_range.min, Operator::PUSH, 1)
expression.append_constant(target_range.min_border,
Operator::PUSH, 1)
expression.append_constant(target_range.max, Operator::PUSH, 1)
expression.append_constant(target_range.max_border,
Operator::PUSH, 1)
expression.append_operator(Operator::CALL, 5)
end
filtered_count_n_records(table, filter) do |expression|
expression_builder.build_partial_min_and_max(expression)
end
end
end
Expand All @@ -113,48 +67,14 @@ def filtered_count_n_records(table, filter)

begin
expression = Expression.create(table)
if block_given?
yield(expression)
if filter
expression.parse(filter)
expression.append_operator(Operator::AND, 2)
end
else
expression.parse(filter)
end
yield(expression)
filtered_table = table.select(expression)
filtered_table.size
ensure
filtered_table.close if filtered_table
expression.close if expression
end
end

def count_n_records_in_range(range_index,
min, min_border, max, max_border)
flags = TableCursorFlags::BY_KEY
case min_border
when :include
flags |= TableCursorFlags::GE
when :exclude
flags |= TableCursorFlags::GT
end
case max_border
when :include
flags |= TableCursorFlags::LE
when :exclude
flags |= TableCursorFlags::LT
end

TableCursor.open(range_index.table,
:min => min,
:max => max,
:flags => flags) do |table_cursor|
IndexCursor.open(table_cursor, range_index) do |index_cursor|
index_cursor.count
end
end
end
end
end
end
72 changes: 12 additions & 60 deletions plugins/sharding/logical_range_filter.rb
Expand Up @@ -152,6 +152,10 @@ def initialize(context, table, shard_key, shard_range)
@target_range = @context.enumerator.target_range

@cover_type = @target_range.cover_type(@shard_range)

@expression_builder = RangeExpressionBuilder.new(@shard_key,
@target_range,
@filter)
end

def execute
Expand All @@ -175,7 +179,7 @@ def execute
nil, nil)
else
filter_table do |expression|
build_expression_partial_min(expression)
@expression_builder.build_partial_min(expression)
end
end
when :partial_max
Expand All @@ -185,7 +189,7 @@ def execute
@target_range.max, @target_range.max_border)
else
filter_table do |expression|
build_expression_partial_max(expression)
@expression_builder.build_partial_max(expression)
end
end
when :partial_min_and_max
Expand All @@ -195,65 +199,13 @@ def execute
@target_range.max, @target_range.max_border)
else
filter_table do |expression|
build_expression_partial_min_and_max(expression)
@expression_builder.build_partial_min_and_max(expression)
end
end
end
end

private
def build_expression_all(expression)
expression.parse(@filter)
end

def build_expression_partial_min(expression)
expression.append_object(@shard_key, Operator::PUSH, 1)
expression.append_operator(Operator::GET_VALUE, 1)
expression.append_constant(@target_range.min, Operator::PUSH, 1)
if @target_range.min_border == :include
expression.append_operator(Operator::GREATER_EQUAL, 2)
else
expression.append_operator(Operator::GREATER, 2)
end
if @filter
expression.parse(@filter)
expression.append_operator(Operator::AND, 2)
end
end

def build_expression_partial_max(expression)
expression.append_object(@shard_key, Operator::PUSH, 1)
expression.append_operator(Operator::GET_VALUE, 1)
expression.append_constant(@target_range.max, Operator::PUSH, 1)
if @target_range.max_border == :include
expression.append_operator(Operator::LESS_EQUAL, 2)
else
expression.append_operator(Operator::LESS, 2)
end
if @filter
expression.parse(@filter)
expression.append_operator(Operator::AND, 2)
end
end

def build_expression_partial_min_and_max(expression)
between = Groonga::Context.instance["between"]
expression.append_object(between, Operator::PUSH, 1)
expression.append_object(@shard_key, Operator::PUSH, 1)
expression.append_operator(Operator::GET_VALUE, 1)
expression.append_constant(@target_range.min, Operator::PUSH, 1)
expression.append_constant(@target_range.min_border,
Operator::PUSH, 1)
expression.append_constant(@target_range.max, Operator::PUSH, 1)
expression.append_constant(@target_range.max_border,
Operator::PUSH, 1)
expression.append_operator(Operator::CALL, 5)
if @filter
expression.parse(@filter)
expression.append_operator(Operator::AND, 2)
end
end

def use_range_index?(range_index)
required_n_records = @context.current_offset + @context.current_limit
max_n_records = @table.size
Expand All @@ -271,25 +223,25 @@ def use_range_index?(range_index)
when :all
if @filter
create_expression(@table) do |expression|
build_expression_all(expression)
@expression_builder.build_all(expression)
estimated_n_records = expression.estimate_size(@table)
end
else
estimated_n_records = max_n_records
end
when :partial_min
create_expression(@table) do |expression|
build_expression_partial_min(expression)
@expression_builder.build_partial_min(expression)
estimated_n_records = expression.estimate_size(@table)
end
when :partial_max
create_expression(@table) do |expression|
build_expression_partial_max(expression)
@expression_builder.build_partial_max(expression)
estimated_n_records = expression.estimate_size(@table)
end
when :partial_min_and_max
create_expression(@table) do |expression|
build_expression_partial_min_and_max(expression)
@expression_builder.build_partial_min_and_max(expression)
estimated_n_records = expression.estimate_size(@table)
end
end
Expand Down Expand Up @@ -322,7 +274,7 @@ def filter_shard_all(range_index)
nil, nil)
else
filter_table do |expression|
build_expression_all(expression)
@expression_builder.build_all(expression)
end
end
end
Expand Down
65 changes: 65 additions & 0 deletions plugins/sharding/range_expression_builder.rb
@@ -0,0 +1,65 @@
module Groonga
module Sharding
class RangeExpressionBuilder
def initialize(key, target_range, filter)
@key = key
@target_range = target_range
@filter = filter
end

def build_all(expression)
return if @filter.nil?

expression.parse(@filter)
end

def build_partial_min(expression)
expression.append_object(@key, Operator::PUSH, 1)
expression.append_operator(Operator::GET_VALUE, 1)
expression.append_constant(@target_range.min, Operator::PUSH, 1)
if @target_range.min_border == :include
expression.append_operator(Operator::GREATER_EQUAL, 2)
else
expression.append_operator(Operator::GREATER, 2)
end
if @filter
expression.parse(@filter)
expression.append_operator(Operator::AND, 2)
end
end

def build_partial_max(expression)
expression.append_object(@key, Operator::PUSH, 1)
expression.append_operator(Operator::GET_VALUE, 1)
expression.append_constant(@target_range.max, Operator::PUSH, 1)
if @target_range.max_border == :include
expression.append_operator(Operator::LESS_EQUAL, 2)
else
expression.append_operator(Operator::LESS, 2)
end
if @filter
expression.parse(@filter)
expression.append_operator(Operator::AND, 2)
end
end

def build_partial_min_and_max(expression)
between = Groonga::Context.instance["between"]
expression.append_object(between, Operator::PUSH, 1)
expression.append_object(@key, Operator::PUSH, 1)
expression.append_operator(Operator::GET_VALUE, 1)
expression.append_constant(@target_range.min, Operator::PUSH, 1)
expression.append_constant(@target_range.min_border,
Operator::PUSH, 1)
expression.append_constant(@target_range.max, Operator::PUSH, 1)
expression.append_constant(@target_range.max_border,
Operator::PUSH, 1)
expression.append_operator(Operator::CALL, 5)
if @filter
expression.parse(@filter)
expression.append_operator(Operator::AND, 2)
end
end
end
end
end
3 changes: 2 additions & 1 deletion plugins/sharding/sources.am
@@ -1,4 +1,5 @@
sharding_scripts = \
logical_count.rb \
logical_enumerator.rb \
logical_range_filter.rb
logical_range_filter.rb \
range_expression_builder.rb

0 comments on commit 3e01aac

Please sign in to comment.