Skip to content

Commit c727038

Browse files
author
huangxiyuan
committed
Optimize performance of x to struct
1 parent b80d8a9 commit c727038

File tree

8 files changed

+369
-135
lines changed

8 files changed

+369
-135
lines changed

bson_reader.h

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ struct BsonDoc {
7575

7676
class BsonReader:public XReader<BsonReader> {
7777
public:
78+
friend xdoc_type;
7879
using xdoc_type::convert;
7980
BsonReader(const uint8_t*data, size_t length, bool copy=true):xdoc_type(0, ""),_doc(new BsonDoc) {
8081
init(data, length, copy);
@@ -107,39 +108,51 @@ class BsonReader:public XReader<BsonReader> {
107108
}
108109
}
109110
public:
110-
void convert(std::string &val) {
111+
#define XTOSTRUCT_BSON_GETVAL(rtype, f) \
112+
const BsonValue *v = get_val(key); \
113+
if (NULL != v) { \
114+
val = (rtype) f(&v->root); \
115+
return true; \
116+
} else return false
117+
bool convert(const char *key, std::string &val) {
118+
const BsonValue *v = get_val(key);
119+
if (NULL == v) {
120+
return false;
121+
}
122+
111123
uint32_t length;
112-
const char* data = bson_iter_utf8(&_val->root, &length);
124+
const char* data = bson_iter_utf8(&v->root, &length);
113125
if (0 != data) {
114126
val = std::string(data, length);
115127
}
128+
return true;
116129
}
117-
void convert(bool &val) {
118-
val = (bool)bson_iter_as_int64(&_val->root);
130+
bool convert(const char *key, bool &val) {
131+
XTOSTRUCT_BSON_GETVAL(bool, bson_iter_as_int64);
119132
}
120-
void convert(int16_t &val) {
121-
val = (int16_t)bson_iter_as_int64(&_val->root);
133+
bool convert(const char *key, int16_t &val) {
134+
XTOSTRUCT_BSON_GETVAL(int16_t, bson_iter_as_int64);
122135
}
123-
void convert(uint16_t &val) {
124-
val = (uint16_t)bson_iter_as_int64(&_val->root);
136+
bool convert(const char *key, uint16_t &val) {
137+
XTOSTRUCT_BSON_GETVAL(uint16_t, bson_iter_as_int64);
125138
}
126-
void convert(int32_t &val) {
127-
val = (int32_t)bson_iter_as_int64(&_val->root);
139+
bool convert(const char *key, int32_t &val) {
140+
XTOSTRUCT_BSON_GETVAL(int32_t, bson_iter_as_int64);
128141
}
129-
void convert(uint32_t &val) {
130-
val = (uint32_t)bson_iter_as_int64(&_val->root);
142+
bool convert(const char *key, uint32_t &val) {
143+
XTOSTRUCT_BSON_GETVAL(uint32_t, bson_iter_as_int64);
131144
}
132-
void convert(int64_t &val) {
133-
val = bson_iter_as_int64(&_val->root);
145+
bool convert(const char *key, int64_t &val) {
146+
XTOSTRUCT_BSON_GETVAL(int64_t, bson_iter_as_int64);
134147
}
135-
void convert(uint64_t &val) {
136-
val = (uint64_t)bson_iter_as_int64(&_val->root);
148+
bool convert(const char *key, uint64_t &val) {
149+
XTOSTRUCT_BSON_GETVAL(uint64_t, bson_iter_as_int64);
137150
}
138-
void convert(double &val) {
139-
val = bson_iter_double(&_val->root);
151+
bool convert(const char *key, double &val) {
152+
XTOSTRUCT_BSON_GETVAL(double, bson_iter_double);
140153
}
141-
void convert(float &val) {
142-
val = (float)bson_iter_double(&_val->root);
154+
bool convert(const char *key, float &val) {
155+
XTOSTRUCT_BSON_GETVAL(float, bson_iter_double);
143156
}
144157

145158
const std::string& type() {
@@ -217,6 +230,9 @@ class BsonReader:public XReader<BsonReader> {
217230
bson_iter_init(&root, &b);
218231
_val = _doc->Get(&root, true);
219232
}
233+
234+
BsonReader():xdoc_type(0, ""),_data(0), _doc(0),_val(0) {
235+
}
220236
BsonReader(BsonValue* val, const BsonReader*parent, const char*key):xdoc_type(parent, key),_val(val) {
221237
_doc = 0;
222238
_data = 0;
@@ -226,6 +242,33 @@ class BsonReader:public XReader<BsonReader> {
226242
_data = 0;
227243
}
228244

245+
BsonReader* child(const char*key, BsonReader*tmp) {
246+
bson_objs_type::iterator iter;
247+
if (NULL!=_val && _val->objs.end()!=(iter=_val->objs.find(key))) {
248+
tmp->_key = key;
249+
tmp->_parent = this;
250+
tmp->_val = _val->doc->Get(&iter->second);
251+
return tmp;
252+
} else {
253+
return NULL;
254+
}
255+
}
256+
257+
const BsonValue* get_val(const char *key) {
258+
if (NULL == key) {
259+
return _val;
260+
} else if (NULL != _val) {
261+
bson_objs_type::iterator iter = _val->objs.find(key);
262+
if (iter != _val->objs.end()) {
263+
return _val->doc->Get(&iter->second);
264+
} else {
265+
return NULL;
266+
}
267+
} else {
268+
return NULL;
269+
}
270+
}
271+
229272
const uint8_t* _data;
230273
BsonDoc *_doc;
231274
mutable BsonValue *_val;

config_reader.h

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class ConfigReader:public XReader<ConfigReader> {
3131
typedef libconfig::Setting CONFIG_READER_VALUE;
3232
typedef libconfig::SettingConstIterator CONFIG_READER_ITERATOR;
3333
public:
34+
friend xdoc_type;
3435
using xdoc_type::convert;
3536

3637
ConfigReader(const std::string& str, bool isfile=false, const std::string&root=""):xdoc_type(0, ""),_doc(new CONFIG_READER_DOCUMENT),_val(0) {
@@ -76,35 +77,47 @@ class ConfigReader:public XReader<ConfigReader> {
7677
}
7778
}
7879
public: // convert
79-
void convert(std::string &val) {
80-
val = _val->c_str();
80+
#define XTOSTRUCT_CONFIG_GETVAL(...) \
81+
const CONFIG_READER_VALUE *v = get_val(key); \
82+
if (NULL != v) { \
83+
val = __VA_ARGS__(*v); \
84+
return true; \
85+
} else return false
86+
bool convert(const char *key, std::string &val) {
87+
const CONFIG_READER_VALUE *v = get_val(key);
88+
if (NULL != v) {
89+
val = v->c_str();
90+
return true;
91+
} else {
92+
return false;
93+
}
8194
}
82-
void convert(bool &val) {
83-
val = *_val;
95+
bool convert(const char *key, bool &val) {
96+
XTOSTRUCT_CONFIG_GETVAL();
8497
}
85-
void convert(int16_t &val) {
86-
val = (int16_t)(int)(*_val);
98+
bool convert(const char *key, int16_t &val) {
99+
XTOSTRUCT_CONFIG_GETVAL((int16_t)(int));
87100
}
88-
void convert(uint16_t &val) {
89-
val = (uint16_t)(int)(*_val);
101+
bool convert(const char *key, uint16_t &val) {
102+
XTOSTRUCT_CONFIG_GETVAL((uint16_t)(int));
90103
}
91-
void convert(int32_t &val) {
92-
val = *_val;
104+
bool convert(const char *key, int32_t &val) {
105+
XTOSTRUCT_CONFIG_GETVAL();
93106
}
94-
void convert(uint32_t &val) {
95-
val = *_val;
107+
bool convert(const char *key, uint32_t &val) {
108+
XTOSTRUCT_CONFIG_GETVAL();
96109
}
97-
void convert(int64_t &val) {
98-
val = *_val;
110+
bool convert(const char *key, int64_t &val) {
111+
XTOSTRUCT_CONFIG_GETVAL();
99112
}
100-
void convert(uint64_t &val) {
101-
val = *_val;
113+
bool convert(const char *key, uint64_t &val) {
114+
XTOSTRUCT_CONFIG_GETVAL();
102115
}
103-
void convert(double &val) {
104-
val = *_val;
116+
bool convert(const char *key, double &val) {
117+
XTOSTRUCT_CONFIG_GETVAL();
105118
}
106-
void convert(float &val) {
107-
val = *_val;
119+
bool convert(const char *key, float &val) {
120+
XTOSTRUCT_CONFIG_GETVAL();
108121
}
109122

110123
const std::string& type() {
@@ -189,6 +202,9 @@ class ConfigReader:public XReader<ConfigReader> {
189202
}
190203

191204
private:
205+
ConfigReader():xdoc_type(0, ""),_doc(0),_val(0) {
206+
init();
207+
}
192208
ConfigReader(const CONFIG_READER_VALUE* val, const ConfigReader*parent, const char*key):xdoc_type(parent, key),_doc(0),_val(val) {
193209
init();
194210
}
@@ -199,6 +215,27 @@ class ConfigReader:public XReader<ConfigReader> {
199215
_iter = 0;
200216
}
201217

218+
ConfigReader* child(const char*key, ConfigReader*tmp) {
219+
if (NULL!=_val && _val->exists(key)) {
220+
tmp->_key = key;
221+
tmp->_parent = this;
222+
tmp->_val = &(*_val)[key];
223+
return tmp;
224+
} else {
225+
return NULL;
226+
}
227+
}
228+
229+
const CONFIG_READER_VALUE* get_val(const char *key) {
230+
if (NULL == key) {
231+
return _val;
232+
} else if (NULL != _val && _val->exists(key)) {
233+
return &(*_val)[key];
234+
} else {
235+
return NULL;
236+
}
237+
}
238+
202239
CONFIG_READER_DOCUMENT* _doc;
203240
const CONFIG_READER_VALUE* _val;
204241
mutable CONFIG_READER_ITERATOR* _iter;

json_reader.h

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace x2struct {
3030

3131
class JsonReader:public XReader<JsonReader> {
3232
public:
33+
friend xdoc_type;
3334
using xdoc_type::convert;
3435

3536
JsonReader(const std::string& str, bool isfile=false):xdoc_type(0, ""),_doc(new rapidjson::Document),_val(_doc) {
@@ -45,9 +46,9 @@ class JsonReader:public XReader<JsonReader> {
4546
}
4647
std::string _tmp((std::istreambuf_iterator<char>(fs)), std::istreambuf_iterator<char>());
4748
data.swap(_tmp);
48-
_doc->Parse(data);
49+
_doc->Parse(data); //Insitu((char *)_raw.c_str());
4950
} else {
50-
_doc->Parse(str);
51+
_doc->Parse(str); //Insitu((char *)_raw.c_str());
5152
}
5253

5354
if (_doc->HasParseError()) {
@@ -82,35 +83,42 @@ class JsonReader:public XReader<JsonReader> {
8283
}
8384
}
8485
public: // convert
85-
void convert(std::string &val) {
86-
val = _val->GetString();
86+
#define XTOSTRUCT_JSON_GETVAL(f, ...) \
87+
const rapidjson::Value *v = get_val(key); \
88+
if (NULL != v) { \
89+
val = __VA_ARGS__ v->f(); \
90+
return true; \
91+
} else return false
92+
93+
bool convert(const char*key, std::string &val) {
94+
XTOSTRUCT_JSON_GETVAL(GetString);
8795
}
88-
void convert(bool &val) {
89-
val = _val->GetBool();
96+
bool convert(const char*key, bool &val) {
97+
XTOSTRUCT_JSON_GETVAL(GetBool);
9098
}
91-
void convert(int16_t &val) {
92-
val = (int16_t)_val->GetInt();
99+
bool convert(const char*key, int16_t &val) {
100+
XTOSTRUCT_JSON_GETVAL(GetInt, (int16_t));
93101
}
94-
void convert(uint16_t &val) {
95-
val = (uint16_t)_val->GetUint();
102+
bool convert(const char*key, uint16_t &val) {
103+
XTOSTRUCT_JSON_GETVAL(GetInt, (uint16_t));
96104
}
97-
void convert(int32_t &val) {
98-
val = _val->GetInt();
105+
bool convert(const char*key, int32_t &val) {
106+
XTOSTRUCT_JSON_GETVAL(GetInt);
99107
}
100-
void convert(uint32_t &val) {
101-
val = _val->GetUint();
108+
bool convert(const char*key, uint32_t &val) {
109+
XTOSTRUCT_JSON_GETVAL(GetUint);
102110
}
103-
void convert(int64_t &val) {
104-
val = _val->GetInt64();
111+
bool convert(const char*key, int64_t &val) {
112+
XTOSTRUCT_JSON_GETVAL(GetInt64);
105113
}
106-
void convert(uint64_t &val) {
107-
val = _val->GetUint64();
114+
bool convert(const char*key, uint64_t &val) {
115+
XTOSTRUCT_JSON_GETVAL(GetUint64);
108116
}
109-
void convert(double &val) {
110-
val = _val->GetDouble();
117+
bool convert(const char*key, double &val) {
118+
XTOSTRUCT_JSON_GETVAL(GetDouble);
111119
}
112-
void convert(float &val) {
113-
val = _val->GetFloat();
120+
bool convert(const char*key, float &val) {
121+
XTOSTRUCT_JSON_GETVAL(GetFloat);
114122
}
115123

116124
const std::string& type() {
@@ -178,6 +186,9 @@ class JsonReader:public XReader<JsonReader> {
178186
}
179187

180188
private:
189+
JsonReader():xdoc_type(0, ""),_doc(0),_val(0) {
190+
init();
191+
}
181192
JsonReader(const rapidjson::Value* val, const JsonReader*parent, const char*key):xdoc_type(parent, key),_doc(0),_val(val) {
182193
init();
183194
}
@@ -187,7 +198,35 @@ class JsonReader:public XReader<JsonReader> {
187198
void init() {
188199
_iter = 0;
189200
}
201+
202+
JsonReader* child(const char*key, JsonReader*tmp) {
203+
rapidjson::Value::ConstMemberIterator iter;
204+
if (NULL!=_val && _val->MemberEnd()!=(iter=_val->FindMember(key))) {
205+
tmp->_key = key;
206+
tmp->_parent = this;
207+
tmp->_val = &iter->value;
208+
return tmp;
209+
} else {
210+
return NULL;
211+
}
212+
}
213+
214+
const rapidjson::Value* get_val(const char *key) {
215+
if (NULL == key) {
216+
return _val;
217+
} else if (NULL != _val) {
218+
rapidjson::Value::ConstMemberIterator iter = _val->FindMember(key);
219+
if (iter != _val->MemberEnd()) {
220+
return &iter->value;
221+
} else {
222+
return NULL;
223+
}
224+
} else {
225+
return NULL;
226+
}
227+
}
190228

229+
//std::string _raw;
191230
rapidjson::Document* _doc;
192231
const rapidjson::Value* _val;
193232
mutable rapidjson::Value::ConstMemberIterator* _iter;

test/check.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ TEST(config, marshal)
150150
}
151151
#endif
152152

153+
#ifdef XTOSTRUCT_XML
153154
TEST(xml, unmarshal)
154155
{
155156
xstruct x;
@@ -168,6 +169,7 @@ TEST(xml, marshal)
168169
X::loadxml(n, y, false);
169170
base_check(y);
170171
}
172+
#endif
171173

172174
#ifdef XTOSTRUCT_BSON
173175
TEST(bson, unmarshal)
@@ -268,7 +270,7 @@ TEST(performance, parse)
268270
TEST(performance, convert)
269271
{
270272
vector<int> m_v;
271-
m_obj->convert(m_v);
273+
m_obj->convert(NULL, m_v);
272274
EXPECT_EQ(m_v.size(), 1024U);
273275
}
274276

0 commit comments

Comments
 (0)