Module: sip-router Branch: master Commit: 7449e6a6e9d064ca39413ada8a9fbf64da8a22fd URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=7449e6a6e9d064ca39413ada8a9fbf64da8a22fd
Author: Daniel-Constantin Mierla <mico...@gmail.com> Committer: Daniel-Constantin Mierla <mico...@gmail.com> Date: Mon Mar 15 11:55:44 2010 +0100 mtree: load many trees from same table - support to load data for different trees from same table - this is a different operating mode, where tree names are dynamic, it is no need to define them via parameters - static tree definition takes priority (if a static tree is defined, the table with dynamic trees name is not loaded) --- modules/mtree/mtree.c | 84 ++++++++++++++++++++- modules/mtree/mtree.h | 5 + modules/mtree/mtree_mod.c | 182 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 257 insertions(+), 14 deletions(-) diff --git a/modules/mtree/mtree.c b/modules/mtree/mtree.c index 615472c..54f82da 100644 --- a/modules/mtree/mtree.c +++ b/modules/mtree/mtree.c @@ -50,6 +50,9 @@ static m_tree_t **_ptree = NULL; /* quick transaltion table */ unsigned char _mt_char_table[256]; +/** + * + */ void mt_char_table_init(void) { unsigned int i; @@ -59,6 +62,39 @@ void mt_char_table_init(void) _mt_char_table[(unsigned int)mt_char_list.s[i]] = (unsigned char)i; } + +/** + * + */ +m_tree_t *mt_swap_list_head(m_tree_t *ntree) +{ + m_tree_t *otree; + + otree = *_ptree; + *_ptree = ntree; + + return otree; +} + +/** + * + */ +int mt_init_list_head(void) +{ + if(_ptree!=NULL) + return 0; + _ptree = (m_tree_t**)shm_malloc( sizeof(m_tree_t*) ); + if (_ptree==0) { + LM_ERR("out of shm mem for pdtree\n"); + return -1; + } + *_ptree=0; + return 0; +} + +/** + * + */ m_tree_t* mt_init_tree(str* tname, str *dbtable, int type) { m_tree_t *pt = NULL; @@ -629,7 +665,8 @@ int mt_table_spec(char* val) it = it->next; } - if(it!=NULL || str_strcmp(&it->tname, &tmp.tname)==0) + /* found */ + if(it!=NULL && str_strcmp(&it->tname, &tmp.tname)==0) { LM_ERR("duplicate tree with name [%s]\n", tmp.tname.s); goto error; @@ -663,6 +700,51 @@ error: return -1; } +m_tree_t *mt_add_tree(m_tree_t **dpt, str *tname, str *dbtable, int type) +{ + m_tree_t *it = NULL; + m_tree_t *prev = NULL; + m_tree_t *ndl = NULL; + + if(dpt==NULL) + return NULL; + + it = *dpt; + prev = NULL; + /* search the it position before which to insert new tvalue */ + while(it!=NULL && str_strcmp(&it->tname, tname)<0) + { + prev = it; + it = it->next; + } + + if(it!=NULL && str_strcmp(&it->tname, tname)==0) + { + return it; + } + /* add new tname*/ + if(it==NULL || str_strcmp(&it->tname, tname)>0) + { + LM_DBG("adding new tname [%s]\n", tname->s); + + ndl = mt_init_tree(tname, dbtable, type); + if(ndl==NULL) + { + LM_ERR("no more shm memory\n"); + return NULL; + } + + ndl->next = it; + + /* new tvalue must be added as first element */ + if(prev==NULL) + *dpt = ndl; + else + prev->next=ndl; + } + return ndl; +} + void mt_destroy_trees(void) { if (_ptree!=NULL) diff --git a/modules/mtree/mtree.h b/modules/mtree/mtree.h index 5a1d9ec..0bacb90 100644 --- a/modules/mtree/mtree.h +++ b/modules/mtree/mtree.h @@ -83,5 +83,10 @@ int mt_table_spec(char* val); void mt_destroy_trees(void); int mt_defined_trees(void); +m_tree_t *mt_swap_list_head(m_tree_t *ntree); +int mt_init_list_head(void); +m_tree_t *mt_add_tree(m_tree_t **dpt, str *tname, str *dbtable, + int type); + #endif diff --git a/modules/mtree/mtree_mod.c b/modules/mtree/mtree_mod.c index 4d7d154..3c204a6 100644 --- a/modules/mtree/mtree_mod.c +++ b/modules/mtree/mtree_mod.c @@ -61,10 +61,20 @@ CREATE TABLE mtree ( tvalue VARCHAR(128) DEFAULT '' NOT NULL, CONSTRAINT tprefix_idx UNIQUE (tprefix) ) ENGINE=MyISAM; +INSERT INTO version (table_name, table_version) values ('mtrees','1'); +CREATE TABLE mtrees ( + id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL, + tname VARCHAR(128) NOT NULL, + tprefix VARCHAR(32) NOT NULL, + tvalue VARCHAR(128) DEFAULT '' NOT NULL, + CONSTRAINT tname_tprefix_idx UNIQUE (tname, tprefix) +) ENGINE=MyISAM; #endif /** parameters */ static str db_url = str_init(DEFAULT_DB_URL); +static str db_table = str_init(""); +static str tname_column = str_init("tname"); static str tprefix_column = str_init("tprefix"); static str tvalue_column = str_init("tvalue"); @@ -102,7 +112,8 @@ static int mt_match(struct sip_msg *msg, gparam_t *dm, gparam_t *var, static struct mi_root* mt_mi_reload(struct mi_root*, void* param); static struct mi_root* mt_mi_list(struct mi_root*, void* param); -static int mt_load_db(); +static int mt_load_db(str *tname); +static int mt_load_db_trees(); static cmd_export_t cmds[]={ {"mt_match", (cmd_function)w_mt_match, 3, fixup_mt_match, @@ -113,6 +124,8 @@ static cmd_export_t cmds[]={ static param_export_t params[]={ {"mtree", STR_PARAM|USE_FUNC_PARAM, (void*)mt_param}, {"db_url", STR_PARAM, &db_url.s}, + {"db_table", STR_PARAM, &db_table.s}, + {"tname_column", STR_PARAM, &tname_column.s}, {"tprefix_column", STR_PARAM, &tprefix_column.s}, {"tvalue_column", STR_PARAM, &tvalue_column.s}, {"char_list", STR_PARAM, &mt_char_list.s}, @@ -121,6 +134,7 @@ static param_export_t params[]={ {"pv_dstid", STR_PARAM, &dstid_param.s}, {"pv_weight", STR_PARAM, &weight_param.s}, {"pv_count", STR_PARAM, &count_param.s}, + {"_mt_tree_type", INT_PARAM, &_mt_tree_type}, {0, 0, 0} }; @@ -162,6 +176,8 @@ static int mod_init(void) } db_url.len = strlen(db_url.s); + db_table.len = strlen(db_table.s); + tname_column.len = strlen(tname_column.s); tprefix_column.len = strlen(tprefix_column.s); tvalue_column.len = strlen(tvalue_column.s); @@ -243,25 +259,40 @@ static int mod_init(void) goto error1; } - if(!mt_defined_trees()) + if(mt_defined_trees()) { - LM_ERR("no trees defined\n"); - goto error1; - } + LM_DBG("static trees defined\n"); - pt = mt_get_first_tree(); - - while(pt!=NULL) - { + pt = mt_get_first_tree(); + + while(pt!=NULL) + { + /* loading all information from database */ + if(mt_load_db(&pt->tname)!=0) + { + LM_ERR("cannot load info from database\n"); + goto error1; + } + pt = pt->next; + } + } else { + if(db_table.len<=0) + { + LM_ERR("no trees table defined\n"); + goto error1; + } + if(mt_init_list_head()<0) + { + LM_ERR("unable to init trees list head\n"); + goto error1; + } /* loading all information from database */ - if(mt_load_db(&pt->tname)!=0) + if(mt_load_db_trees()!=0) { - LM_ERR("cannot load info from database\n"); + LM_ERR("cannot load trees from database\n"); goto error1; } - pt = pt->next; } - mt_dbf.close(db_con); db_con = 0; @@ -558,6 +589,131 @@ error: return -1; } +static int mt_load_db_trees() +{ + db_key_t db_cols[3] = {&tname_column, &tprefix_column, &tvalue_column}; + str tprefix, tvalue, tname; + db1_res_t* db_res = NULL; + int i, ret; + m_tree_t *new_head = NULL; + m_tree_t *new_tree = NULL; + m_tree_t *old_head = NULL; + + if(db_con==NULL) + { + LM_ERR("no db connection\n"); + return -1; + } + + if (mt_dbf.use_table(db_con, &db_table) < 0) + { + LM_ERR("failed to use_table\n"); + return -1; + } + + if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) + { + if(mt_dbf.query(db_con,0,0,0,db_cols,0,3,&tname_column,0) < 0) + { + LM_ERR("Error while querying db\n"); + return -1; + } + if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) + { + LM_ERR("Error while fetching result\n"); + if (db_res) + mt_dbf.free_result(db_con, db_res); + goto error; + } else { + if(RES_ROW_N(db_res)==0) + { + return 0; + } + } + } else { + if((ret=mt_dbf.query(db_con, NULL, NULL, NULL, db_cols, + 0, 3, &tname_column, &db_res))!=0 + || RES_ROW_N(db_res)<=0 ) + { + mt_dbf.free_result(db_con, db_res); + if( ret==0) + { + return 0; + } else { + goto error; + } + } + } + + do { + for(i=0; i<RES_ROW_N(db_res); i++) + { + /* check for NULL values ?!?! */ + tname.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val); + tname.len = strlen(tname.s); + + tprefix.s = (char*)(RES_ROWS(db_res)[i].values[1].val.string_val); + tprefix.len = strlen(tprefix.s); + + tvalue.s = (char*)(RES_ROWS(db_res)[i].values[2].val.string_val); + tvalue.len = strlen(tvalue.s); + + if(tprefix.s==NULL || tvalue.s==NULL || tname.s==NULL || + tprefix.len<=0 || tvalue.len<=0 || tname.len<=0) + { + LM_ERR("Error - bad values in db\n"); + continue; + } + new_tree = mt_add_tree(&new_head, &tname, &db_table, _mt_tree_type); + if(new_tree==NULL) + { + LM_ERR("New tree cannot be initialized\n"); + goto error; + } + if(mt_add_to_tree(new_tree, &tprefix, &tvalue)<0) + { + LM_ERR("Error adding info to tree\n"); + goto error; + } + } + if (DB_CAPABILITY(mt_dbf, DB_CAP_FETCH)) { + if(mt_dbf.fetch_result(db_con, &db_res, mt_fetch_rows)<0) { + LM_ERR("Error while fetching!\n"); + if (db_res) + mt_dbf.free_result(db_con, db_res); + goto error; + } + } else { + break; + } + } while(RES_ROW_N(db_res)>0); + mt_dbf.free_result(db_con, db_res); + + /* block all readers */ + lock_get( mt_lock ); + mt_reload_flag = 1; + lock_release( mt_lock ); + + while (mt_tree_refcnt) { + sleep_us(10); + } + + old_head = mt_swap_list_head(new_head); + + mt_reload_flag = 0; + /* free old data */ + if (old_head!=NULL) + mt_free_tree(old_head); + + return 0; + +error: + mt_dbf.free_result(db_con, db_res); + if (new_head!=NULL) + mt_free_tree(new_head); + return -1; +} + /**************************** MI ***************************/ /** _______________________________________________ sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev