Kouhei Sutou
null+****@clear*****
Fri Mar 21 17:45:07 JST 2014
Kouhei Sutou 2014-03-21 17:45:07 +0900 (Fri, 21 Mar 2014) New Revision: 0a4ba1be75fc7b1433fb8ec4a8cee8cd4017cdf7 https://github.com/ranguba/rroonga/commit/0a4ba1be75fc7b1433fb8ec4a8cee8cd4017cdf7 Message: Support `{"VALUE" => WEIGHT}` style weight value assignment Modified files: ext/groonga/rb-grn-variable-size-column.c test/test-variable-size-column.rb Modified: ext/groonga/rb-grn-variable-size-column.c (+66 -31) =================================================================== --- ext/groonga/rb-grn-variable-size-column.c 2014-03-21 00:04:13 +0900 (577de95) +++ ext/groonga/rb-grn-variable-size-column.c 2014-03-21 17:45:07 +0900 (587d9f3) @@ -210,6 +210,32 @@ rb_grn_variable_size_column_array_reference (VALUE self, VALUE rb_id) return rb_value; } +typedef struct { + grn_ctx *context; + grn_obj *vector; + grn_obj *element_value; +} HashElementToVectorElementData; + +static int +hash_element_to_vector_element(VALUE key, VALUE value, VALUE user_data) +{ + HashElementToVectorElementData *data = + (HashElementToVectorElementData *)user_data; + unsigned int weight; + + GRN_BULK_REWIND(data->element_value); + RVAL2GRNBULK(key, data->context, data->element_value); + + weight = NUM2UINT(value); + grn_vector_add_element(data->context, data->vector, + GRN_BULK_HEAD(data->element_value), + GRN_BULK_VSIZE(data->element_value), + weight, + data->element_value->header.domain); + + return ST_CONTINUE; +} + /* * It updates a value of variable size column value for the record * that ID is _id_. @@ -329,7 +355,6 @@ rb_grn_variable_size_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value) grn_rc rc; grn_id id; grn_obj *value, *element_value; - int i, n; int flags = GRN_OBJ_SET; rb_grn_variable_size_column_deconstruct(SELF(self), &column, &context, @@ -345,42 +370,52 @@ rb_grn_variable_size_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value) id = RVAL2GRNID(rb_id, context, range, self); - if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cArray))) { + grn_obj_reinit(context, value, + value->header.domain, + value->header.flags | GRN_OBJ_VECTOR); + if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cArray))) { + int i, n; + n = RARRAY_LEN(rb_value); + for (i = 0; i < n; i++) { + unsigned int weight = 0; + VALUE rb_element_value, rb_weight; + + rb_grn_scan_options(RARRAY_PTR(rb_value)[i], + "value", &rb_element_value, + "weight", &rb_weight, + NULL); + + if (!NIL_P(rb_weight)) { + weight = NUM2UINT(rb_weight); + } + + GRN_BULK_REWIND(element_value); + if (!NIL_P(rb_element_value)) { + RVAL2GRNBULK(rb_element_value, context, element_value); + } + + grn_vector_add_element(context, value, + GRN_BULK_HEAD(element_value), + GRN_BULK_VSIZE(element_value), + weight, + element_value->header.domain); + } + } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cHash))) { + HashElementToVectorElementData data; + data.context = context; + data.vector = value; + data.element_value = element_value; + rb_hash_foreach(rb_value, hash_element_to_vector_element, (VALUE)&data); + } else { rb_raise(rb_eArgError, "<%s>: " - "weight vector value must be an array of index value: <%s>", + "weight vector value must be an array of index value or " + "a hash that key is vector value and value is vector weight: " + "<%s>", rb_grn_inspect(self), rb_grn_inspect(rb_value)); } - grn_obj_reinit(context, value, - value->header.domain, - value->header.flags | GRN_OBJ_VECTOR); - n = RARRAY_LEN(rb_value); - for (i = 0; i < n; i++) { - unsigned int weight = 0; - VALUE rb_element_value, rb_weight; - - rb_grn_scan_options(RARRAY_PTR(rb_value)[i], - "value", &rb_element_value, - "weight", &rb_weight, - NULL); - - if (!NIL_P(rb_weight)) { - weight = NUM2UINT(rb_weight); - } - - GRN_BULK_REWIND(element_value); - if (!NIL_P(rb_element_value)) { - RVAL2GRNBULK(rb_element_value, context, element_value); - } - - grn_vector_add_element(context, value, - GRN_BULK_HEAD(element_value), - GRN_BULK_VSIZE(element_value), - weight, - element_value->header.domain); - } rc = grn_obj_set_value(context, column, id, value, flags); rb_grn_context_check(context, self); rb_grn_rc_check(rc, self); Modified: test/test-variable-size-column.rb (+21 -1) =================================================================== --- test/test-variable-size-column.rb 2014-03-21 00:04:13 +0900 (470bcde) +++ test/test-variable-size-column.rb 2014-03-21 17:45:07 +0900 (6e7ee40) @@ -252,7 +252,7 @@ class VariableSizeColumnTest < Test::Unit::TestCase @products = Groonga["Products"] end - def test_accessor + def test_array groonga =****@produ*****("Groonga") groonga.tags = [ { @@ -277,6 +277,26 @@ class VariableSizeColumnTest < Test::Unit::TestCase ], groonga.tags) end + + def test_hash + groonga =****@produ*****("Groonga") + groonga.tags = { + "groonga" => 100, + "full text search" => 1000, + } + + assert_equal([ + { + :value => "groonga", + :weight => 100, + }, + { + :value => "full text search", + :weight => 1000, + }, + ], + groonga.tags) + end end end end -------------- next part -------------- HTML����������������������������... Download