Skip to content

Commit

Permalink
Optimization type.
Browse files Browse the repository at this point in the history
  • Loading branch information
wangbo committed Dec 25, 2013
1 parent e96f5a3 commit 81fa0fe
Show file tree
Hide file tree
Showing 9 changed files with 371 additions and 77 deletions.
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_INIT([libcstl],[2.2.0],[activesys.wb@gmail.com])
AC_COPYRIGHT([Copyright (C) 2008 - 2013 Wangbo.])
AC_INIT([libcstl],[2.3.0],[activesys.wb@gmail.com])
AC_COPYRIGHT([Copyright (C) 2008 - 2014 Wangbo.])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
#LT_INIT
AC_CONFIG_SRCDIR([src/cstl_vector.c])
Expand Down
2 changes: 1 addition & 1 deletion cstl/cstl_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ typedef binary_function_t bfun_t;
/* type style */
typedef enum _tagtypestley
{
_TYPE_INVALID, _TYPE_C_BUILTIN, _TYPE_USER_DEFINE, _TYPE_CSTL_BUILTIN
_TYPE_INVALID = 0, _TYPE_C_BUILTIN, _TYPE_USER_DEFINE, _TYPE_CSTL_BUILTIN
}_typestyle_t;

typedef struct _tagtype
Expand Down
141 changes: 95 additions & 46 deletions src/cstl_types.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,95 @@ void _type_get_type_pair(_typeinfo_t* pt_typeinfofirst, _typeinfo_t* pt_typeinfo
}
}

static inline bool_t _type_cstl_builtin_special(const char* s_typename)
{
/*
* Judging the special cstl-builtin type.
*/
size_t t_length = 0;
bool_t b_result = false;

assert(s_typename != NULL);

t_length = strlen(s_typename);
switch (t_length) {
case 7:
if (strncmp(s_typename, _RANGE_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 8:
if (strncmp(s_typename, _STRING_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 10:
if (strncmp(s_typename, _ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 14:
if (strncmp(s_typename, _SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 15:
if (strncmp(s_typename, _LIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 16:
if (strncmp(s_typename, _INPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _SLIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _DEQUE_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 17:
if (strncmp(s_typename, _STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _OUTPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _VECTOR_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 18:
if (strncmp(s_typename, _FORWARD_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 19:
if (strncmp(s_typename, _MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _HASH_SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _HASH_MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 23:
if (strncmp(s_typename, _BASIC_STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
case 24:
if (strncmp(s_typename, _HASH_MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _HASH_MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _BIDIRECTIONAL_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _RANDOM_ACCESS_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
b_result = true;
}
break;
default:
b_result = false;
break;
}

return b_result;
}

void _type_get_type(_typeinfo_t* pt_typeinfo, const char* s_typename)
{
char s_registeredname[_TYPE_NAME_SIZE + 1] = {'\0'};
char s_registeredname[_TYPE_NAME_SIZE + 1];

assert(pt_typeinfo != NULL);
assert(s_typename != NULL);
Expand All @@ -255,6 +341,7 @@ void _type_get_type(_typeinfo_t* pt_typeinfo, const char* s_typename)
_type_init();
}

s_registeredname[0] = s_registeredname[_TYPE_NAME_SIZE] = '\0';
pt_typeinfo->_t_style = _type_get_style(s_typename, pt_typeinfo->_s_typename);
if (pt_typeinfo->_t_style == _TYPE_INVALID) {
pt_typeinfo->_pt_type = NULL;
Expand All @@ -264,33 +351,16 @@ void _type_get_type(_typeinfo_t* pt_typeinfo, const char* s_typename)
strncpy(s_registeredname, pt_typeinfo->_s_typename, _TYPE_NAME_SIZE);
} else {
/* the string_t , range_t and iterator types are special codition */
if (strncmp(pt_typeinfo->_s_typename, _STRING_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _RANGE_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _INPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _OUTPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _FORWARD_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _BIDIRECTIONAL_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _RANDOM_ACCESS_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _VECTOR_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _LIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _SLIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _DEQUE_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _HASH_SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _HASH_MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _HASH_MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _HASH_MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(pt_typeinfo->_s_typename, _BASIC_STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
if (_type_cstl_builtin_special(pt_typeinfo->_s_typename)) {
strncpy(s_registeredname, pt_typeinfo->_s_typename, _TYPE_NAME_SIZE);
} else {
size_t t_length = 0;
char* pc_leftbracket = strchr(pt_typeinfo->_s_typename, _CSTL_LEFT_BRACKET);
assert(pc_leftbracket != NULL);
strncpy(s_registeredname, pt_typeinfo->_s_typename, pc_leftbracket - pt_typeinfo->_s_typename);
t_length = pc_leftbracket - pt_typeinfo->_s_typename;
assert(t_length <= _TYPE_NAME_SIZE);
strncpy(s_registeredname, pt_typeinfo->_s_typename, t_length);
s_registeredname[t_length] = '\0';
}
}

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

/* the string_t and iterator types are special condition */
if (strncmp(s_typename, _STRING_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _RANGE_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _INPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _OUTPUT_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _FORWARD_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _BIDIRECTIONAL_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _RANDOM_ACCESS_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _VECTOR_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _LIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _SLIST_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _DEQUE_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _HASH_SET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _HASH_MAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _HASH_MULTISET_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _HASH_MULTIMAP_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0 ||
strncmp(s_typename, _BASIC_STRING_ITERATOR_TYPE, _TYPE_NAME_SIZE) == 0) {
if (_type_cstl_builtin_special(s_typename)) {
strncpy(s_elemtypename, s_typename, _TYPE_NAME_SIZE);
} else {
/* e.g. "vector_t<map_t<int,long>>" */
Expand Down
62 changes: 51 additions & 11 deletions src/cstl_types_aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@
}while(false)
#define _TYPE_REGISTER_END()

/* BKDR hash seed */
#define _TYPE_HASH_BKDR_SEED 131

/** local data type declaration and local struct, union, enum section **/

/** local function prototype section **/
Expand Down Expand Up @@ -118,6 +121,9 @@ _typeregister_t _gt_typeregister = {false, {NULL}, {{NULL}, NULL, NULL, 0, 0, 0}
_typeregister_t _gt_typeregister = {false, {NULL}, {0}};
#endif

_typecache_t _gt_typecache[_TYPE_CACHE_COUNT] = {{'\0'}, {'\0'}, 0};
size_t _gt_typecache_index = 0;

/** local global variable definition section **/

/** exported function implementation section **/
Expand All @@ -126,18 +132,18 @@ _typeregister_t _gt_typeregister = {false, {NULL}, {0}};
*/
size_t _type_hash(const char* s_typename)
{
size_t t_namesum = 0;
size_t t_namelen = 0;
size_t i = 0;
/*
* Use BKDR hash function.
*/
size_t t_hash = 0;

assert(s_typename != NULL);

t_namelen = strlen(s_typename);
for (i = 0; i < t_namelen; ++i) {
t_namesum += (size_t)s_typename[i];
while (*s_typename) {
t_hash = t_hash * _TYPE_HASH_BKDR_SEED + (*s_typename++);
}

return t_namesum % _TYPE_REGISTER_BUCKET_COUNT;
return t_hash % _TYPE_REGISTER_BUCKET_COUNT;
}

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

assert(s_typename != NULL);

if (strlen(s_typename) > _TYPE_NAME_SIZE) {
return NULL;
}
assert(strlen(s_typename) <= _TYPE_NAME_SIZE);

/* get the registered type pointer */
pt_node = _gt_typeregister._apt_bucket[_type_hash(s_typename)];
Expand Down Expand Up @@ -355,5 +358,42 @@ void _type_register_cstl_builtin(void)
_TYPE_REGISTER_END();
}

/**
* Find in type style cache and update cache.
*/
_typestyle_t _type_cache_find(const char* s_typename, char* s_formalname)
{
size_t i = 0;

assert(s_typename != NULL);
assert(s_formalname != NULL);

for (i = 0; i < _TYPE_CACHE_COUNT; ++i) {
if (_gt_typecache[i]._t_style == _TYPE_INVALID) {
return _TYPE_INVALID;
} else if (strncmp(s_typename, _gt_typecache[i]._s_typename, _TYPE_NAME_SIZE) == 0) {
strncpy(s_formalname, _gt_typecache[i]._s_formalname, _TYPE_NAME_SIZE);
return _gt_typecache[i]._t_style;
}
}

return _TYPE_INVALID;
}

void _type_cache_update(const char* s_typename, const char* s_formalname, _typestyle_t t_style)
{
assert(s_typename != NULL);
assert(strlen(s_typename) > 0);
assert(s_formalname != NULL);
assert(strlen(s_formalname) > 0);
assert(t_style == _TYPE_C_BUILTIN || t_style == _TYPE_USER_DEFINE || t_style == _TYPE_CSTL_BUILTIN);

strncpy(_gt_typecache[_gt_typecache_index]._s_typename, s_typename, _TYPE_NAME_SIZE);
strncpy(_gt_typecache[_gt_typecache_index]._s_formalname, s_formalname, _TYPE_NAME_SIZE);
_gt_typecache[_gt_typecache_index]._t_style = t_style;

_gt_typecache_index = (++_gt_typecache_index) % _TYPE_CACHE_COUNT;
}

/** eof **/

18 changes: 17 additions & 1 deletion src/cstl_types_aux.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,22 @@ extern "C" {
/** include section **/

/** constant declaration and macro section **/
#define _TYPE_CACHE_COUNT 256

/** data type declaration and struct, union, enum section **/
/**
* type style cache
*/
typedef struct _tagtypecache {
char _s_typename[_TYPE_NAME_SIZE + 1];
char _s_formalname[_TYPE_NAME_SIZE + 1];
_typestyle_t _t_style;
}_typecache_t;

/** exported global variable declaration section **/
extern _typeregister_t _gt_typeregister;
extern _typeregister_t _gt_typeregister;
extern _typecache_t _gt_typecache[_TYPE_CACHE_COUNT];
extern size_t _gt_typecache_index;

/** exported function prototype section **/
/**
Expand All @@ -57,6 +68,11 @@ extern _type_t* _type_is_registered(const char* s_typename);
extern void _type_init(void);
extern void _type_register_c_builtin(void);
extern void _type_register_cstl_builtin(void);
/**
* Find in type style cache and update cache.
*/
extern _typestyle_t _type_cache_find(const char* s_typename, char* s_formalname);
extern void _type_cache_update(const char* s_typename, const char* s_formalname, _typestyle_t t_style);

#ifdef __cplusplus
}
Expand Down
28 changes: 18 additions & 10 deletions src/cstl_types_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,22 +186,23 @@ _typestyle_t _type_get_style(const char* s_typename, char* s_formalname)
/*
* this parser algorithm is associated with BNF in file doc/project/libcstl.bnf.
*/
char s_tokentext[_TYPE_NAME_SIZE + 1];
char s_userdefine[_TYPE_NAME_SIZE + 1];
_typestyle_t t_style = _TYPE_INVALID;
char s_userdefine[_TYPE_NAME_SIZE + 1];
_typestyle_t t_style = _TYPE_INVALID;

assert(s_typename != NULL);
assert(s_formalname != NULL);
assert(strlen(s_typename) <= _TYPE_NAME_SIZE);

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

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

/* initialize the type analysis */
s_userdefine[0] = s_userdefine[_TYPE_NAME_SIZE] = '\0';
memset(_gt_typeanalysis._s_typename, '\0', _TYPE_NAME_SIZE+1);
memset(_gt_typeanalysis._s_tokentext, '\0', _TYPE_NAME_SIZE+1);
_gt_typeanalysis._t_index = 0;
Expand Down Expand Up @@ -285,7 +286,14 @@ _typestyle_t _type_get_style(const char* s_typename, char* s_formalname)
}

_type_get_token();
return _gt_typeanalysis._t_token == _TOKEN_END_OF_INPUT ? t_style : _TYPE_INVALID;
t_style = _gt_typeanalysis._t_token == _TOKEN_END_OF_INPUT ? t_style : _TYPE_INVALID;

/* update type style cache */
if (t_style != _TYPE_INVALID) {
_type_cache_update(s_typename, s_formalname, t_style);
}

return t_style;
}

/**
Expand Down
Loading

0 comments on commit 81fa0fe

Please sign in to comment.