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

Reply via email to