Improve Thrift map deserialization code
Summary: Instead of copy-constructing map values into the map, alter the code such that we insert default-constructed elements into the map and then deserialize them by reference.
Reviewed By: hzhao
Test Plan: Ran the test in test/cpp which include serialization and deserialization of nested maps.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665448 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
index 1b560bc..2518509 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/generate/t_cpp_generator.cc
@@ -70,7 +70,7 @@
// Include the types file
f_types_impl_ <<
- "#include \"" << get_include_prefix(*get_program()) << program_name_ <<
+ "#include \"" << get_include_prefix(*get_program()) << program_name_ <<
"_types.h\"" << endl <<
endl;
@@ -185,14 +185,14 @@
"#ifndef " << program_name_ << "_CONSTANTS_H" << endl <<
"#define " << program_name_ << "_CONSTANTS_H" << endl <<
endl <<
- "#include \"" << get_include_prefix(*get_program()) << program_name_ <<
+ "#include \"" << get_include_prefix(*get_program()) << program_name_ <<
"_types.h\"" << endl <<
endl <<
ns_open_ << endl <<
endl;
f_consts_impl <<
- "#include \"" << get_include_prefix(*get_program()) << program_name_ <<
+ "#include \"" << get_include_prefix(*get_program()) << program_name_ <<
"_constants.h\"" << endl <<
endl <<
ns_open_ << endl <<
@@ -2308,14 +2308,14 @@
t_field fval(tmap->get_val_type(), val);
out <<
- indent() << declare_field(&fkey) << endl <<
- indent() << declare_field(&fval) << endl;
+ indent() << declare_field(&fkey) << endl;
generate_deserialize_field(out, &fkey);
- generate_deserialize_field(out, &fval);
-
indent(out) <<
- prefix << ".insert(std::make_pair(" << key << ", " << val << "));" << endl;
+ declare_field(&fval, false, false, false, true) << " = " <<
+ prefix << "[" << key << "];" << endl;
+
+ generate_deserialize_field(out, &fval);
}
void t_cpp_generator::generate_deserialize_set_element(ofstream& out,
@@ -2701,7 +2701,7 @@
* @param ttype The type
* @return Field declaration, i.e. int x = 0;
*/
-string t_cpp_generator::declare_field(t_field* tfield, bool init, bool pointer, bool constant) {
+string t_cpp_generator::declare_field(t_field* tfield, bool init, bool pointer, bool constant, bool reference) {
// TODO(mcslee): do we ever need to initialize the field?
string result = "";
if (constant) {
@@ -2711,6 +2711,9 @@
if (pointer) {
result += "*";
}
+ if (reference) {
+ result += "&";
+ }
result += " " + tfield->get_name();
if (init) {
t_type* type = get_true_type(tfield->get_type());
@@ -2742,7 +2745,10 @@
result += " = (" + type_name(type) + ")0";
}
}
- return result + ";";
+ if (!reference) {
+ result += ";";
+ }
+ return result;
}
/**
@@ -2887,6 +2893,6 @@
if ((last_slash = include_prefix.rfind("/")) != string::npos) {
return include_prefix.substr(0, last_slash) + "/" + out_dir_base_ + "/";
}
-
+
return "";
}
diff --git a/compiler/cpp/src/generate/t_cpp_generator.h b/compiler/cpp/src/generate/t_cpp_generator.h
index 4bc9783..ba19c1c 100644
--- a/compiler/cpp/src/generate/t_cpp_generator.h
+++ b/compiler/cpp/src/generate/t_cpp_generator.h
@@ -86,18 +86,18 @@
*/
void generate_deserialize_field (std::ofstream& out,
- t_field* tfield,
+ t_field* tfield,
std::string prefix="",
std::string suffix="");
-
+
void generate_deserialize_struct (std::ofstream& out,
t_struct* tstruct,
std::string prefix="");
-
+
void generate_deserialize_container (std::ofstream& out,
t_type* ttype,
std::string prefix="");
-
+
void generate_deserialize_set_element (std::ofstream& out,
t_set* tset,
std::string prefix="");
@@ -144,7 +144,7 @@
std::string namespace_close(std::string ns);
std::string type_name(t_type* ttype, bool in_typedef=false, bool arg=false);
std::string base_type_name(t_base_type::t_base tbase);
- std::string declare_field(t_field* tfield, bool init=false, bool pointer=false, bool constant=false);
+ std::string declare_field(t_field* tfield, bool init=false, bool pointer=false, bool constant=false, bool reference=false);
std::string function_signature(t_function* tfunction, std::string prefix="");
std::string argument_list(t_struct* tstruct);
std::string type_to_enum(t_type* ttype);
@@ -158,7 +158,7 @@
ttype = get_true_type(ttype);
return
- ttype->is_container() ||
+ ttype->is_container() ||
ttype->is_struct() ||
ttype->is_xception() ||
(ttype->is_base_type() && (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING));