Skip to content

Commit 81fa0fe

Browse files
author
wangbo
committed
Optimization type.
1 parent e96f5a3 commit 81fa0fe

9 files changed

+371
-77
lines changed

configure.ac

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# -*- Autoconf -*-
22
# Process this file with autoconf to produce a configure script.
33

4-
AC_INIT([libcstl],[2.2.0],[[email protected]])
5-
AC_COPYRIGHT([Copyright (C) 2008 - 2013 Wangbo.])
4+
AC_INIT([libcstl],[2.3.0],[[email protected]])
5+
AC_COPYRIGHT([Copyright (C) 2008 - 2014 Wangbo.])
66
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
77
#LT_INIT
88
AC_CONFIG_SRCDIR([src/cstl_vector.c])

cstl/cstl_types.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ typedef binary_function_t bfun_t;
149149
/* type style */
150150
typedef enum _tagtypestley
151151
{
152-
_TYPE_INVALID, _TYPE_C_BUILTIN, _TYPE_USER_DEFINE, _TYPE_CSTL_BUILTIN
152+
_TYPE_INVALID = 0, _TYPE_C_BUILTIN, _TYPE_USER_DEFINE, _TYPE_CSTL_BUILTIN
153153
}_typestyle_t;
154154

155155
typedef struct _tagtype

src/cstl_types.c

+95-46
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,95 @@ void _type_get_type_pair(_typeinfo_t* pt_typeinfofirst, _typeinfo_t* pt_typeinfo
244244
}
245245
}
246246

247+
static inline bool_t _type_cstl_builtin_special(const char* s_typename)
248+
{
249+
/*
250+
* Judging the special cstl-builtin type.
251+
*/
252+
size_t t_length = 0;
253+
bool_t b_result = false;
254+
255+
assert(s_typename != NULL);
256+
257+
t_length = strlen(s_typename);
258+
switch (t_length) {
259+
case 7:
260+
if (strncmp(s_typename, _RANGE_TYPE, _TYPE_NAME_SIZE) == 0) {
261+
b_result = true;
262+
}
263+
break;
264+
case 8:
265+
if (strncmp(s_typename, _STRING_TYPE, _TYPE_NAME_SIZE) == 0) {
266+
b_result = true;
267+
}
268+
break;
269+
case 10:
270+
if (strncmp(s_typename, _ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
271+
b_result = true;
272+
}
273+
break;
274+
case 14:
275+
if (strncmp(s_typename, _SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
276+
strncmp(s_typename, _MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
277+
b_result = true;
278+
}
279+
break;
280+
case 15:
281+
if (strncmp(s_typename, _LIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
282+
b_result = true;
283+
}
284+
break;
285+
case 16:
286+
if (strncmp(s_typename, _INPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
287+
strncmp(s_typename, _SLIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
288+
strncmp(s_typename, _DEQUE_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
289+
b_result = true;
290+
}
291+
break;
292+
case 17:
293+
if (strncmp(s_typename, _STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
294+
strncmp(s_typename, _OUTPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
295+
strncmp(s_typename, _VECTOR_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
296+
b_result = true;
297+
}
298+
break;
299+
case 18:
300+
if (strncmp(s_typename, _FORWARD_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
301+
b_result = true;
302+
}
303+
break;
304+
case 19:
305+
if (strncmp(s_typename, _MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
306+
strncmp(s_typename, _MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
307+
strncmp(s_typename, _HASH_SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
308+
strncmp(s_typename, _HASH_MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
309+
b_result = true;
310+
}
311+
break;
312+
case 23:
313+
if (strncmp(s_typename, _BASIC_STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
314+
b_result = true;
315+
}
316+
break;
317+
case 24:
318+
if (strncmp(s_typename, _HASH_MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
319+
strncmp(s_typename, _HASH_MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
320+
strncmp(s_typename, _BIDIRECTIONAL_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
321+
strncmp(s_typename, _RANDOM_ACCESS_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
322+
b_result = true;
323+
}
324+
break;
325+
default:
326+
b_result = false;
327+
break;
328+
}
329+
330+
return b_result;
331+
}
332+
247333
void _type_get_type(_typeinfo_t* pt_typeinfo, const char* s_typename)
248334
{
249-
char s_registeredname[_TYPE_NAME_SIZE + 1] = {'\0'};
335+
char s_registeredname[_TYPE_NAME_SIZE + 1];
250336

251337
assert(pt_typeinfo != NULL);
252338
assert(s_typename != NULL);
@@ -255,6 +341,7 @@ void _type_get_type(_typeinfo_t* pt_typeinfo, const char* s_typename)
255341
_type_init();
256342
}
257343

344+
s_registeredname[0] = s_registeredname[_TYPE_NAME_SIZE] = '\0';
258345
pt_typeinfo->_t_style = _type_get_style(s_typename, pt_typeinfo->_s_typename);
259346
if (pt_typeinfo->_t_style == _TYPE_INVALID) {
260347
pt_typeinfo->_pt_type = NULL;
@@ -264,33 +351,16 @@ void _type_get_type(_typeinfo_t* pt_typeinfo, const char* s_typename)
264351
strncpy(s_registeredname, pt_typeinfo->_s_typename, _TYPE_NAME_SIZE);
265352
} else {
266353
/* the string_t , range_t and iterator types are special codition */
267-
if (strncmp(pt_typeinfo->_s_typename, _STRING_TYPE, _TYPE_NAME_SIZE) == 0 ||
268-
strncmp(pt_typeinfo->_s_typename, _RANGE_TYPE, _TYPE_NAME_SIZE) == 0 ||
269-
strncmp(pt_typeinfo->_s_typename, _ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
270-
strncmp(pt_typeinfo->_s_typename, _INPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
271-
strncmp(pt_typeinfo->_s_typename, _OUTPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
272-
strncmp(pt_typeinfo->_s_typename, _FORWARD_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
273-
strncmp(pt_typeinfo->_s_typename, _BIDIRECTIONAL_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
274-
strncmp(pt_typeinfo->_s_typename, _RANDOM_ACCESS_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
275-
strncmp(pt_typeinfo->_s_typename, _VECTOR_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
276-
strncmp(pt_typeinfo->_s_typename, _LIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
277-
strncmp(pt_typeinfo->_s_typename, _SLIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
278-
strncmp(pt_typeinfo->_s_typename, _DEQUE_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
279-
strncmp(pt_typeinfo->_s_typename, _SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
280-
strncmp(pt_typeinfo->_s_typename, _MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
281-
strncmp(pt_typeinfo->_s_typename, _MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
282-
strncmp(pt_typeinfo->_s_typename, _MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
283-
strncmp(pt_typeinfo->_s_typename, _HASH_SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
284-
strncmp(pt_typeinfo->_s_typename, _HASH_MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
285-
strncmp(pt_typeinfo->_s_typename, _HASH_MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
286-
strncmp(pt_typeinfo->_s_typename, _HASH_MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
287-
strncmp(pt_typeinfo->_s_typename, _STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
288-
strncmp(pt_typeinfo->_s_typename, _BASIC_STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
354+
if (_type_cstl_builtin_special(pt_typeinfo->_s_typename)) {
289355
strncpy(s_registeredname, pt_typeinfo->_s_typename, _TYPE_NAME_SIZE);
290356
} else {
357+
size_t t_length = 0;
291358
char* pc_leftbracket = strchr(pt_typeinfo->_s_typename, _CSTL_LEFT_BRACKET);
292359
assert(pc_leftbracket != NULL);
293-
strncpy(s_registeredname, pt_typeinfo->_s_typename, pc_leftbracket - pt_typeinfo->_s_typename);
360+
t_length = pc_leftbracket - pt_typeinfo->_s_typename;
361+
assert(t_length <= _TYPE_NAME_SIZE);
362+
strncpy(s_registeredname, pt_typeinfo->_s_typename, t_length);
363+
s_registeredname[t_length] = '\0';
294364
}
295365
}
296366

@@ -445,28 +515,7 @@ void _type_get_elem_typename(const char* s_typename, char* s_elemtypename)
445515
memset(s_elemtypename, '\0', _TYPE_NAME_SIZE + 1);
446516

447517
/* the string_t and iterator types are special condition */
448-
if (strncmp(s_typename, _STRING_TYPE, _TYPE_NAME_SIZE) == 0 ||
449-
strncmp(s_typename, _RANGE_TYPE, _TYPE_NAME_SIZE) == 0 ||
450-
strncmp(s_typename, _ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
451-
strncmp(s_typename, _INPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
452-
strncmp(s_typename, _OUTPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
453-
strncmp(s_typename, _FORWARD_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
454-
strncmp(s_typename, _BIDIRECTIONAL_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
455-
strncmp(s_typename, _RANDOM_ACCESS_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
456-
strncmp(s_typename, _VECTOR_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
457-
strncmp(s_typename, _LIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
458-
strncmp(s_typename, _SLIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
459-
strncmp(s_typename, _DEQUE_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
460-
strncmp(s_typename, _SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
461-
strncmp(s_typename, _MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
462-
strncmp(s_typename, _MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
463-
strncmp(s_typename, _MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
464-
strncmp(s_typename, _HASH_SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
465-
strncmp(s_typename, _HASH_MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
466-
strncmp(s_typename, _HASH_MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
467-
strncmp(s_typename, _HASH_MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
468-
strncmp(s_typename, _STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
469-
strncmp(s_typename, _BASIC_STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
518+
if (_type_cstl_builtin_special(s_typename)) {
470519
strncpy(s_elemtypename, s_typename, _TYPE_NAME_SIZE);
471520
} else {
472521
/* e.g. "vector_t<map_t<int,long>>" */

src/cstl_types_aux.c

+51-11
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@
7575
}while(false)
7676
#define _TYPE_REGISTER_END()
7777

78+
/* BKDR hash seed */
79+
#define _TYPE_HASH_BKDR_SEED 131
80+
7881
/** local data type declaration and local struct, union, enum section **/
7982

8083
/** local function prototype section **/
@@ -118,6 +121,9 @@ _typeregister_t _gt_typeregister = {false, {NULL}, {{NULL}, NULL, NULL, 0, 0, 0}
118121
_typeregister_t _gt_typeregister = {false, {NULL}, {0}};
119122
#endif
120123

124+
_typecache_t _gt_typecache[_TYPE_CACHE_COUNT] = {{'\0'}, {'\0'}, 0};
125+
size_t _gt_typecache_index = 0;
126+
121127
/** local global variable definition section **/
122128

123129
/** exported function implementation section **/
@@ -126,18 +132,18 @@ _typeregister_t _gt_typeregister = {false, {NULL}, {0}};
126132
*/
127133
size_t _type_hash(const char* s_typename)
128134
{
129-
size_t t_namesum = 0;
130-
size_t t_namelen = 0;
131-
size_t i = 0;
135+
/*
136+
* Use BKDR hash function.
137+
*/
138+
size_t t_hash = 0;
132139

133140
assert(s_typename != NULL);
134141

135-
t_namelen = strlen(s_typename);
136-
for (i = 0; i < t_namelen; ++i) {
137-
t_namesum += (size_t)s_typename[i];
142+
while (*s_typename) {
143+
t_hash = t_hash * _TYPE_HASH_BKDR_SEED + (*s_typename++);
138144
}
139145

140-
return t_namesum % _TYPE_REGISTER_BUCKET_COUNT;
146+
return t_hash % _TYPE_REGISTER_BUCKET_COUNT;
141147
}
142148

143149
/**
@@ -149,10 +155,7 @@ _type_t* _type_is_registered(const char* s_typename)
149155
_typenode_t* pt_node = NULL;
150156

151157
assert(s_typename != NULL);
152-
153-
if (strlen(s_typename) > _TYPE_NAME_SIZE) {
154-
return NULL;
155-
}
158+
assert(strlen(s_typename) <= _TYPE_NAME_SIZE);
156159

157160
/* get the registered type pointer */
158161
pt_node = _gt_typeregister._apt_bucket[_type_hash(s_typename)];
@@ -355,5 +358,42 @@ void _type_register_cstl_builtin(void)
355358
_TYPE_REGISTER_END();
356359
}
357360

361+
/**
362+
* Find in type style cache and update cache.
363+
*/
364+
_typestyle_t _type_cache_find(const char* s_typename, char* s_formalname)
365+
{
366+
size_t i = 0;
367+
368+
assert(s_typename != NULL);
369+
assert(s_formalname != NULL);
370+
371+
for (i = 0; i < _TYPE_CACHE_COUNT; ++i) {
372+
if (_gt_typecache[i]._t_style == _TYPE_INVALID) {
373+
return _TYPE_INVALID;
374+
} else if (strncmp(s_typename, _gt_typecache[i]._s_typename, _TYPE_NAME_SIZE) == 0) {
375+
strncpy(s_formalname, _gt_typecache[i]._s_formalname, _TYPE_NAME_SIZE);
376+
return _gt_typecache[i]._t_style;
377+
}
378+
}
379+
380+
return _TYPE_INVALID;
381+
}
382+
383+
void _type_cache_update(const char* s_typename, const char* s_formalname, _typestyle_t t_style)
384+
{
385+
assert(s_typename != NULL);
386+
assert(strlen(s_typename) > 0);
387+
assert(s_formalname != NULL);
388+
assert(strlen(s_formalname) > 0);
389+
assert(t_style == _TYPE_C_BUILTIN || t_style == _TYPE_USER_DEFINE || t_style == _TYPE_CSTL_BUILTIN);
390+
391+
strncpy(_gt_typecache[_gt_typecache_index]._s_typename, s_typename, _TYPE_NAME_SIZE);
392+
strncpy(_gt_typecache[_gt_typecache_index]._s_formalname, s_formalname, _TYPE_NAME_SIZE);
393+
_gt_typecache[_gt_typecache_index]._t_style = t_style;
394+
395+
_gt_typecache_index = (++_gt_typecache_index) % _TYPE_CACHE_COUNT;
396+
}
397+
358398
/** eof **/
359399

src/cstl_types_aux.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,22 @@ extern "C" {
3030
/** include section **/
3131

3232
/** constant declaration and macro section **/
33+
#define _TYPE_CACHE_COUNT 256
3334

3435
/** data type declaration and struct, union, enum section **/
36+
/**
37+
* type style cache
38+
*/
39+
typedef struct _tagtypecache {
40+
char _s_typename[_TYPE_NAME_SIZE + 1];
41+
char _s_formalname[_TYPE_NAME_SIZE + 1];
42+
_typestyle_t _t_style;
43+
}_typecache_t;
3544

3645
/** exported global variable declaration section **/
37-
extern _typeregister_t _gt_typeregister;
46+
extern _typeregister_t _gt_typeregister;
47+
extern _typecache_t _gt_typecache[_TYPE_CACHE_COUNT];
48+
extern size_t _gt_typecache_index;
3849

3950
/** exported function prototype section **/
4051
/**
@@ -57,6 +68,11 @@ extern _type_t* _type_is_registered(const char* s_typename);
5768
extern void _type_init(void);
5869
extern void _type_register_c_builtin(void);
5970
extern void _type_register_cstl_builtin(void);
71+
/**
72+
* Find in type style cache and update cache.
73+
*/
74+
extern _typestyle_t _type_cache_find(const char* s_typename, char* s_formalname);
75+
extern void _type_cache_update(const char* s_typename, const char* s_formalname, _typestyle_t t_style);
6076

6177
#ifdef __cplusplus
6278
}

src/cstl_types_parse.c

+18-10
Original file line numberDiff line numberDiff line change
@@ -186,22 +186,23 @@ _typestyle_t _type_get_style(const char* s_typename, char* s_formalname)
186186
/*
187187
* this parser algorithm is associated with BNF in file doc/project/libcstl.bnf.
188188
*/
189-
char s_tokentext[_TYPE_NAME_SIZE + 1];
190-
char s_userdefine[_TYPE_NAME_SIZE + 1];
191-
_typestyle_t t_style = _TYPE_INVALID;
189+
char s_userdefine[_TYPE_NAME_SIZE + 1];
190+
_typestyle_t t_style = _TYPE_INVALID;
192191

193192
assert(s_typename != NULL);
194193
assert(s_formalname != NULL);
194+
assert(strlen(s_typename) <= _TYPE_NAME_SIZE);
195195

196-
if (strlen(s_typename) > _TYPE_NAME_SIZE) {
197-
return _TYPE_INVALID;
198-
}
196+
/* initialize an array efficently */
197+
s_formalname[0] = s_formalname[_TYPE_NAME_SIZE] = '\0';
199198

200-
memset(s_formalname, '\0', _TYPE_NAME_SIZE+1);
201-
memset(s_tokentext, '\0', _TYPE_NAME_SIZE+1);
202-
memset(s_userdefine, '\0', _TYPE_NAME_SIZE+1);
199+
/* find type style cache */
200+
if ((t_style = _type_cache_find(s_typename, s_formalname)) != _TYPE_INVALID) {
201+
return t_style;
202+
}
203203

204204
/* initialize the type analysis */
205+
s_userdefine[0] = s_userdefine[_TYPE_NAME_SIZE] = '\0';
205206
memset(_gt_typeanalysis._s_typename, '\0', _TYPE_NAME_SIZE+1);
206207
memset(_gt_typeanalysis._s_tokentext, '\0', _TYPE_NAME_SIZE+1);
207208
_gt_typeanalysis._t_index = 0;
@@ -285,7 +286,14 @@ _typestyle_t _type_get_style(const char* s_typename, char* s_formalname)
285286
}
286287

287288
_type_get_token();
288-
return _gt_typeanalysis._t_token == _TOKEN_END_OF_INPUT ? t_style : _TYPE_INVALID;
289+
t_style = _gt_typeanalysis._t_token == _TOKEN_END_OF_INPUT ? t_style : _TYPE_INVALID;
290+
291+
/* update type style cache */
292+
if (t_style != _TYPE_INVALID) {
293+
_type_cache_update(s_typename, s_formalname, t_style);
294+
}
295+
296+
return t_style;
289297
}
290298

291299
/**

0 commit comments

Comments
 (0)