Kouhei Sutou
null+****@clear*****
Fri Sep 12 23:34:57 JST 2014
Kouhei Sutou 2014-09-12 23:34:57 +0900 (Fri, 12 Sep 2014) New Revision: 5e3f08ccd013359c55904cf0dbdea2792b935334 https://github.com/groonga/groonga/commit/5e3f08ccd013359c55904cf0dbdea2792b935334 Message: mrb: support optimize for "X > 0 && X < 10" X > 0 && X < 10 -> between(X, 0, "exclude", 10, "exclude") X >= 0 && X < 10 -> between(X, 0, "include", 10, "exclude") X > 0 && X <= 10 -> between(X, 0, "exclude", 10, "include") X >= 0 && X <= 10 -> between(X, 0, "include", 10, "include") Added files: test/command/suite/select/filter/range/less_than_and_greater_than.expected test/command/suite/select/filter/range/less_than_and_greater_than.test test/command/suite/select/filter/range/less_than_and_greater_than_or_equal.expected test/command/suite/select/filter/range/less_than_and_greater_than_or_equal.test test/command/suite/select/filter/range/less_than_or_equal_and_greater_than.expected test/command/suite/select/filter/range/less_than_or_equal_and_greater_than.test test/command/suite/select/filter/range/less_than_or_equal_and_greater_than_or_equal.expected test/command/suite/select/filter/range/less_than_or_equal_and_greater_than_or_equal.test Modified files: lib/mrb/scripts/scan_info_builder.rb Modified: lib/mrb/scripts/scan_info_builder.rb (+98 -1) =================================================================== --- lib/mrb/scripts/scan_info_builder.rb 2014-09-12 23:34:08 +0900 (0d88f40) +++ lib/mrb/scripts/scan_info_builder.rb 2014-09-12 23:34:57 +0900 (55a6476) @@ -123,7 +123,7 @@ module Groonga put_logical_op(@operator, n_codes) end - @data_list + optimize end private @@ -239,5 +239,102 @@ module Groonga end end end + + def optimize + optimized_data_list = [] + i = 0 + n = @data_list.size + while i < n + data = @data_list[i] + next_data = @data_list[i + 1] + i += 1 + if next_data.nil? + optimized_data_list << data + next + end + if range_operations?(data, next_data) + between_data = create_between_data(data, next_data) + optimized_data_list << between_data + next + end + optimized_data_list << data + end + optimized_data_list + end + + def range_operations?(data, next_data) + return false unless next_data.logical_op == Operator::AND + + op, next_op = data.op, next_data.op + return false if !(lower_condition?(op) or lower_condition?(next_op)) + return false if !(upper_condition?(op) or upper_condition?(next_op)) + + data.args[0] == next_data.args[0] and data.indexes == next_data.indexes + end + + def lower_condition?(operator) + case operator + when Operator::GREATER, Operator::GREATER_EQUAL + true + else + false + end + end + + def upper_condition?(operator) + case operator + when Operator::LESS, Operator::LESS_EQUAL + true + else + false + end + end + + def create_between_data(data, next_data) + between_data = ScanInfoData.new(data.start) + between_data.end = next_data.end + between_data.op = Operator::CALL + between_data.logical_op = data.logical_op + between_data.args = create_between_data_args(data, next_data) + between_data.indexes = data.indexes + between_data + end + + def create_between_data_args(data, next_data) + between = Context.instance["between"] + @expression.take_object(between) + column = data.args[0] + op, next_op = data.op, next_data.op + if lower_condition?(op) + min = data.args[1] + min_operator = op + max = next_data.args[1] + max_operator = next_op + else + min = next_data.args[1] + min_operator = next_op + max = data.args[1] + max_operator = op + end + if min_operator == Operator::GREATER + min_border = "exclude" + else + min_border = "include" + end + if max_operator == Operator::LESS + max_border = "exclude" + else + max_border = "include" + end + + [ + between, + column, + min, + @expression.allocate_constant(min_border), + max, + @expression.allocate_constant(max_border), + ] + end end end Added: test/command/suite/select/filter/range/less_than_and_greater_than.expected (+51 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/range/less_than_and_greater_than.expected 2014-09-12 23:34:57 +0900 (48702b1) @@ -0,0 +1,51 @@ +table_create Users TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Users age COLUMN_SCALAR Int32 +[[0,0.0,0.0],true] +table_create Ages TABLE_PAT_KEY Int32 +[[0,0.0,0.0],true] +column_create Ages users_age COLUMN_INDEX Users age +[[0,0.0,0.0],true] +load --table Users +[ +{"_key": "alice", "age": 17}, +{"_key": "bob", "age": 18}, +{"_key": "calros", "age": 19}, +{"_key": "dave", "age": 20}, +{"_key": "eric", "age": 21} +] +[[0,0.0,0.0],5] +select Users --filter 'age > 18 && age < 20' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 1 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "_key", + "ShortText" + ], + [ + "age", + "Int32" + ] + ], + [ + 3, + "calros", + 19 + ] + ] + ] +] Added: test/command/suite/select/filter/range/less_than_and_greater_than.test (+16 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/range/less_than_and_greater_than.test 2014-09-12 23:34:57 +0900 (660895c) @@ -0,0 +1,16 @@ +table_create Users TABLE_HASH_KEY ShortText +column_create Users age COLUMN_SCALAR Int32 + +table_create Ages TABLE_PAT_KEY Int32 +column_create Ages users_age COLUMN_INDEX Users age + +load --table Users +[ +{"_key": "alice", "age": 17}, +{"_key": "bob", "age": 18}, +{"_key": "calros", "age": 19}, +{"_key": "dave", "age": 20}, +{"_key": "eric", "age": 21} +] + +select Users --filter 'age > 18 && age < 20' Added: test/command/suite/select/filter/range/less_than_and_greater_than_or_equal.expected (+56 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/range/less_than_and_greater_than_or_equal.expected 2014-09-12 23:34:57 +0900 (368c754) @@ -0,0 +1,56 @@ +table_create Users TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Users age COLUMN_SCALAR Int32 +[[0,0.0,0.0],true] +table_create Ages TABLE_PAT_KEY Int32 +[[0,0.0,0.0],true] +column_create Ages users_age COLUMN_INDEX Users age +[[0,0.0,0.0],true] +load --table Users +[ +{"_key": "alice", "age": 17}, +{"_key": "bob", "age": 18}, +{"_key": "calros", "age": 19}, +{"_key": "dave", "age": 20}, +{"_key": "eric", "age": 21} +] +[[0,0.0,0.0],5] +select Users --filter 'age > 18 && age <= 20' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 2 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "_key", + "ShortText" + ], + [ + "age", + "Int32" + ] + ], + [ + 3, + "calros", + 19 + ], + [ + 4, + "dave", + 20 + ] + ] + ] +] Added: test/command/suite/select/filter/range/less_than_and_greater_than_or_equal.test (+16 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/range/less_than_and_greater_than_or_equal.test 2014-09-12 23:34:57 +0900 (ef75d7c) @@ -0,0 +1,16 @@ +table_create Users TABLE_HASH_KEY ShortText +column_create Users age COLUMN_SCALAR Int32 + +table_create Ages TABLE_PAT_KEY Int32 +column_create Ages users_age COLUMN_INDEX Users age + +load --table Users +[ +{"_key": "alice", "age": 17}, +{"_key": "bob", "age": 18}, +{"_key": "calros", "age": 19}, +{"_key": "dave", "age": 20}, +{"_key": "eric", "age": 21} +] + +select Users --filter 'age > 18 && age <= 20' Added: test/command/suite/select/filter/range/less_than_or_equal_and_greater_than.expected (+56 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/range/less_than_or_equal_and_greater_than.expected 2014-09-12 23:34:57 +0900 (72a7342) @@ -0,0 +1,56 @@ +table_create Users TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Users age COLUMN_SCALAR Int32 +[[0,0.0,0.0],true] +table_create Ages TABLE_PAT_KEY Int32 +[[0,0.0,0.0],true] +column_create Ages users_age COLUMN_INDEX Users age +[[0,0.0,0.0],true] +load --table Users +[ +{"_key": "alice", "age": 17}, +{"_key": "bob", "age": 18}, +{"_key": "calros", "age": 19}, +{"_key": "dave", "age": 20}, +{"_key": "eric", "age": 21} +] +[[0,0.0,0.0],5] +select Users --filter 'age >= 18 && age < 20' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 2 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "_key", + "ShortText" + ], + [ + "age", + "Int32" + ] + ], + [ + 2, + "bob", + 18 + ], + [ + 3, + "calros", + 19 + ] + ] + ] +] Added: test/command/suite/select/filter/range/less_than_or_equal_and_greater_than.test (+16 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/range/less_than_or_equal_and_greater_than.test 2014-09-12 23:34:57 +0900 (5e4b273) @@ -0,0 +1,16 @@ +table_create Users TABLE_HASH_KEY ShortText +column_create Users age COLUMN_SCALAR Int32 + +table_create Ages TABLE_PAT_KEY Int32 +column_create Ages users_age COLUMN_INDEX Users age + +load --table Users +[ +{"_key": "alice", "age": 17}, +{"_key": "bob", "age": 18}, +{"_key": "calros", "age": 19}, +{"_key": "dave", "age": 20}, +{"_key": "eric", "age": 21} +] + +select Users --filter 'age >= 18 && age < 20' Added: test/command/suite/select/filter/range/less_than_or_equal_and_greater_than_or_equal.expected (+61 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/range/less_than_or_equal_and_greater_than_or_equal.expected 2014-09-12 23:34:57 +0900 (d303a23) @@ -0,0 +1,61 @@ +table_create Users TABLE_HASH_KEY ShortText +[[0,0.0,0.0],true] +column_create Users age COLUMN_SCALAR Int32 +[[0,0.0,0.0],true] +table_create Ages TABLE_PAT_KEY Int32 +[[0,0.0,0.0],true] +column_create Ages users_age COLUMN_INDEX Users age +[[0,0.0,0.0],true] +load --table Users +[ +{"_key": "alice", "age": 17}, +{"_key": "bob", "age": 18}, +{"_key": "calros", "age": 19}, +{"_key": "dave", "age": 20}, +{"_key": "eric", "age": 21} +] +[[0,0.0,0.0],5] +select Users --filter 'age >= 18 && age <= 20' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 3 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "_key", + "ShortText" + ], + [ + "age", + "Int32" + ] + ], + [ + 2, + "bob", + 18 + ], + [ + 3, + "calros", + 19 + ], + [ + 4, + "dave", + 20 + ] + ] + ] +] Added: test/command/suite/select/filter/range/less_than_or_equal_and_greater_than_or_equal.test (+16 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/filter/range/less_than_or_equal_and_greater_than_or_equal.test 2014-09-12 23:34:57 +0900 (49ace87) @@ -0,0 +1,16 @@ +table_create Users TABLE_HASH_KEY ShortText +column_create Users age COLUMN_SCALAR Int32 + +table_create Ages TABLE_PAT_KEY Int32 +column_create Ages users_age COLUMN_INDEX Users age + +load --table Users +[ +{"_key": "alice", "age": 17}, +{"_key": "bob", "age": 18}, +{"_key": "calros", "age": 19}, +{"_key": "dave", "age": 20}, +{"_key": "eric", "age": 21} +] + +select Users --filter 'age >= 18 && age <= 20' -------------- next part -------------- HTML����������������������������...Download