From d1df20a20d1f23321bfdd9ca06ab03a71ceba51d Mon Sep 17 00:00:00 2001 From: Bryan Duxbury Date: Wed, 15 Jun 2011 20:52:57 +0000 Subject: [PATCH] THRIFT-418. rb: Don't do runtime sorting of struct fields A simpler version of the already-committed patch. Patch: Ilya Maykov git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1136189 13f79535-47bb-0310-9956-ffa450edef68 --- compiler/cpp/src/generate/t_rb_generator.cc | 8 ++------ lib/rb/ext/constants.h | 1 - lib/rb/ext/struct.c | 9 +++++---- lib/rb/ext/thrift_native.c | 2 -- lib/rb/lib/thrift/struct_union.rb | 11 ++++++++++- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/compiler/cpp/src/generate/t_rb_generator.cc b/compiler/cpp/src/generate/t_rb_generator.cc index 895026fd..8ae44055 100644 --- a/compiler/cpp/src/generate/t_rb_generator.cc +++ b/compiler/cpp/src/generate/t_rb_generator.cc @@ -620,13 +620,9 @@ void t_rb_generator::generate_field_defns(std::ofstream& out, t_struct* tstruct) indent_down(); out << endl; indent(out) << "}" << endl << endl; - - // Generate the pre-sorted array of field ids, used for iterating through the fields in sorted order. - indent(out) << "FIELD_IDS = FIELDS.keys.sort" << endl << endl; - + indent(out) << "def struct_fields; FIELDS; end" << endl << endl; - - indent(out) << "def struct_field_ids; FIELD_IDS; end" << endl << endl; + } void t_rb_generator::generate_field_data(std::ofstream& out, t_type* field_type, diff --git a/lib/rb/ext/constants.h b/lib/rb/ext/constants.h index 38b1d61d..57df544b 100644 --- a/lib/rb/ext/constants.h +++ b/lib/rb/ext/constants.h @@ -77,7 +77,6 @@ extern ID read_all_method_id; extern ID native_qmark_method_id; extern ID fields_const_id; -extern ID field_ids_const_id; extern ID transport_ivar_id; extern ID strict_read_ivar_id; extern ID strict_write_ivar_id; diff --git a/lib/rb/ext/struct.c b/lib/rb/ext/struct.c index 4455c1c5..dae338e6 100644 --- a/lib/rb/ext/struct.c +++ b/lib/rb/ext/struct.c @@ -55,10 +55,10 @@ ID setvalue_id; ID to_s_method_id; ID name_to_id_method_id; +static ID sorted_field_ids_method_id; #define IS_CONTAINER(ttype) ((ttype) == TTYPE_MAP || (ttype) == TTYPE_LIST || (ttype) == TTYPE_SET) #define STRUCT_FIELDS(obj) rb_const_get(CLASS_OF(obj), fields_const_id) -#define STRUCT_FIELD_IDS(obj) rb_const_get(CLASS_OF(obj), field_ids_const_id) //------------------------------------------- // Writing section @@ -376,11 +376,11 @@ static VALUE rb_thrift_struct_write(VALUE self, VALUE protocol) { // iterate through all the fields here VALUE struct_fields = STRUCT_FIELDS(self); - VALUE struct_field_ids_ordered = STRUCT_FIELD_IDS(self); + VALUE sorted_field_ids = rb_funcall(self, sorted_field_ids_method_id, 0); int i = 0; - for (i=0; i < RARRAY_LEN(struct_field_ids_ordered); i++) { - VALUE field_id = rb_ary_entry(struct_field_ids_ordered, i); + for (i=0; i < RARRAY_LEN(sorted_field_ids); i++) { + VALUE field_id = rb_ary_entry(sorted_field_ids, i); VALUE field_info = rb_hash_aref(struct_fields, field_id); @@ -713,4 +713,5 @@ void Init_struct() { to_s_method_id = rb_intern("to_s"); name_to_id_method_id = rb_intern("name_to_id"); + sorted_field_ids_method_id = rb_intern("sorted_field_ids"); } diff --git a/lib/rb/ext/thrift_native.c b/lib/rb/ext/thrift_native.c index 2a61a3ef..09b9fe49 100644 --- a/lib/rb/ext/thrift_native.c +++ b/lib/rb/ext/thrift_native.c @@ -92,7 +92,6 @@ ID native_qmark_method_id; // constant ids ID fields_const_id; -ID field_ids_const_id; ID transport_ivar_id; ID strict_read_ivar_id; ID strict_write_ivar_id; @@ -175,7 +174,6 @@ void Init_thrift_native() { // constant ids fields_const_id = rb_intern("FIELDS"); - field_ids_const_id = rb_intern("FIELD_IDS"); transport_ivar_id = rb_intern("@trans"); strict_read_ivar_id = rb_intern("@strict_read"); strict_write_ivar_id = rb_intern("@strict_write"); diff --git a/lib/rb/lib/thrift/struct_union.rb b/lib/rb/lib/thrift/struct_union.rb index 86275080..6be7ee7d 100644 --- a/lib/rb/lib/thrift/struct_union.rb +++ b/lib/rb/lib/thrift/struct_union.rb @@ -32,8 +32,17 @@ module Thrift names_to_ids[name] end + def sorted_field_ids + sorted_field_ids = self.class.instance_variable_get(:@sorted_field_ids) + unless sorted_field_ids + sorted_field_ids = struct_fields.keys.sort + self.class.instance_variable_set(:@sorted_field_ids, sorted_field_ids) + end + sorted_field_ids + end + def each_field - struct_field_ids.each do |fid| + sorted_field_ids.each do |fid| data = struct_fields[fid] yield fid, data end -- 2.17.1