Explorar el Código

- applied patch from Carsten Bock - support for db fetch in loading the dialogs (closes #1998043)

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@4555 689a6050-402a-0410-94f2-e92a70836424
Daniel-Constantin Mierla hace 17 años
padre
commit
68c8b77d0c

+ 110 - 92
modules_k/dialog/README

@@ -10,8 +10,8 @@ Bogdan-Andrei Iancu
 
    Copyright © 2006 voice-system.ro
    Revision History
-   Revision $Revision$ $Date: 2008-03-19 20:31:30 +0100
-                              (Mi, 19 Mär 2008) $
+   Revision $Revision$ $Date: 2008-03-19 21:31:30 +0200
+                              (Wed, 19 Mar 2008) $
      __________________________________________________________
 
    Table of Contents
@@ -39,27 +39,28 @@ Bogdan-Andrei Iancu
               1.5.9. db_url (string)
               1.5.10. db_mode (integer)
               1.5.11. db_update_period (integer)
-              1.5.12. table_name (string)
-              1.5.13. callid_column (string)
-              1.5.14. from_uri_column (string)
-              1.5.15. from_tag_column (string)
-              1.5.16. to_uri_column (string)
-              1.5.17. to_tag_column (string)
-              1.5.18. caller_cseq_column (string)
-              1.5.19. callee_cseq_column (string)
-              1.5.20. caller_route_column (string)
-              1.5.21. callee_route_column (string)
-              1.5.22. caller_contact_column (string)
-              1.5.23. callee_contact_column (string)
-              1.5.24. caller_sock_column (string)
-              1.5.25. callee_sock_column (string)
-              1.5.26. h_id_column (string)
-              1.5.27. h_entry_column (string)
-              1.5.28. state_column (string)
-              1.5.29. start_time_column (string)
-              1.5.30. timeout_column (string)
-              1.5.31. profiles_with_value (string)
-              1.5.32. profiles_no_value (string)
+              1.5.12. db_fetch_rows (integer)
+              1.5.13. table_name (string)
+              1.5.14. callid_column (string)
+              1.5.15. from_uri_column (string)
+              1.5.16. from_tag_column (string)
+              1.5.17. to_uri_column (string)
+              1.5.18. to_tag_column (string)
+              1.5.19. caller_cseq_column (string)
+              1.5.20. callee_cseq_column (string)
+              1.5.21. caller_route_column (string)
+              1.5.22. callee_route_column (string)
+              1.5.23. caller_contact_column (string)
+              1.5.24. callee_contact_column (string)
+              1.5.25. caller_sock_column (string)
+              1.5.26. callee_sock_column (string)
+              1.5.27. h_id_column (string)
+              1.5.28. h_entry_column (string)
+              1.5.29. state_column (string)
+              1.5.30. start_time_column (string)
+              1.5.31. timeout_column (string)
+              1.5.32. profiles_with_value (string)
+              1.5.33. profiles_no_value (string)
 
         1.6. Exported Functions
 
@@ -111,30 +112,31 @@ Bogdan-Andrei Iancu
    1.9. Set db_url parameter
    1.10. Set db_mode parameter
    1.11. Set db_update_period parameter
-   1.12. Set table_name parameter
-   1.13. Set callid_column parameter
-   1.14. Set from_uri_column parameter
-   1.15. Set from_tag_column parameter
-   1.16. Set to_uri_column parameter
-   1.17. Set to_tag_column parameter
-   1.18. Set caller_cseq_column parameter
-   1.19. Set callee_cseq_column parameter
-   1.20. Set caller_route_column parameter
-   1.21. Set to_route_column parameter
-   1.22. Set caller_contact_column parameter
-   1.23. Set callee_contact_column parameter
-   1.24. Set caller_sock_column parameter
-   1.25. Set callee_sock_column parameter
-   1.26. Set h_id_column parameter
-   1.27. Set h_entry_column parameter
-   1.28. Set state_column parameter
-   1.29. Set start_time_column parameter
-   1.30. Set timeout_column parameter
-   1.31. Set profiles_with_value parameter
-   1.32. Set profiles_no_value parameter
-   1.33. set_dlg_profile usage
-   1.34. is_in_profile usage
-   1.35. get_profile_size usage
+   1.12. Set db_fetch_rows parameter
+   1.13. Set table_name parameter
+   1.14. Set callid_column parameter
+   1.15. Set from_uri_column parameter
+   1.16. Set from_tag_column parameter
+   1.17. Set to_uri_column parameter
+   1.18. Set to_tag_column parameter
+   1.19. Set caller_cseq_column parameter
+   1.20. Set callee_cseq_column parameter
+   1.21. Set caller_route_column parameter
+   1.22. Set to_route_column parameter
+   1.23. Set caller_contact_column parameter
+   1.24. Set callee_contact_column parameter
+   1.25. Set caller_sock_column parameter
+   1.26. Set callee_sock_column parameter
+   1.27. Set h_id_column parameter
+   1.28. Set h_entry_column parameter
+   1.29. Set state_column parameter
+   1.30. Set start_time_column parameter
+   1.31. Set timeout_column parameter
+   1.32. Set profiles_with_value parameter
+   1.33. Set profiles_no_value parameter
+   1.34. set_dlg_profile usage
+   1.35. is_in_profile usage
+   1.36. get_profile_size usage
 
 Chapter 1. Admin Guide
 
@@ -370,251 +372,267 @@ modparam("dialog", "db_mode", 1)
 modparam("dialog", "db_update_period", 120)
 ...
 
-1.5.12. table_name (string)
+1.5.12. db_fetch_rows (integer)
+
+   The number of the rows to be fetched at once from database when
+   loading the dialog records at startup from the database. This
+   value can be used to tune the load time at startup. For 1MB of
+   private memory (default) it should be below 400. The database
+   driver must support fetch_result() capability. A value of 0
+   means the functionality is disabled.
+
+   Default value is "200".
+
+   Example 1.12. Set db_fetch_rows parameter
+...
+modparam("dialog", "db_fetch_rows", 500)
+...
+
+1.5.13. table_name (string)
 
    If you want to store the information about the dialogs in a
    database a table name must be specified.
 
    Default value is "dialog".
 
-   Example 1.12. Set table_name parameter
+   Example 1.13. Set table_name parameter
 ...
 modparam("dialog", "table_name", "my_dialog")
 ...
 
-1.5.13. callid_column (string)
+1.5.14. callid_column (string)
 
    The column's name in the database to store the dialogs' callid.
 
    Default value is "callid".
 
-   Example 1.13. Set callid_column parameter
+   Example 1.14. Set callid_column parameter
 ...
 modparam("dialog", "callid_column", "callid_c_name")
 ...
 
-1.5.14. from_uri_column (string)
+1.5.15. from_uri_column (string)
 
    The column's name in the database to store the caller's sip
    address.
 
    Default value is "from_uri".
 
-   Example 1.14. Set from_uri_column parameter
+   Example 1.15. Set from_uri_column parameter
 ...
 modparam("dialog", "from_uri_column", "from_uri_c_name")
 ...
 
-1.5.15. from_tag_column (string)
+1.5.16. from_tag_column (string)
 
    The column's name in the database to store the From tag from
    the Invite request.
 
    Default value is "from_tag".
 
-   Example 1.15. Set from_tag_column parameter
+   Example 1.16. Set from_tag_column parameter
 ...
 modparam("dialog", "from_tag_column", "from_tag_c_name")
 ...
 
-1.5.16. to_uri_column (string)
+1.5.17. to_uri_column (string)
 
    The column's name in the database to store the calee's sip
    address.
 
    Default value is "to_uri".
 
-   Example 1.16. Set to_uri_column parameter
+   Example 1.17. Set to_uri_column parameter
 ...
 modparam("dialog", "to_uri_column", "to_uri_c_name")
 ...
 
-1.5.17. to_tag_column (string)
+1.5.18. to_tag_column (string)
 
    The column's name in the database to store the To tag from the
    200 OK response to the Invite request, if present.
 
    Default value is "to_tag".
 
-   Example 1.17. Set to_tag_column parameter
+   Example 1.18. Set to_tag_column parameter
 ...
 modparam("dialog", "to_tag_column", "to_tag_c_name")
 ...
 
-1.5.18. caller_cseq_column (string)
+1.5.19. caller_cseq_column (string)
 
    The column's name in the database to store the cseq from caller
    side.
 
    Default value is "caller_cseq".
 
-   Example 1.18. Set caller_cseq_column parameter
+   Example 1.19. Set caller_cseq_column parameter
 ...
 modparam("dialog", "caller_cseq_column", "column_name")
 ...
 
-1.5.19. callee_cseq_column (string)
+1.5.20. callee_cseq_column (string)
 
    The column's name in the database to store the cseq from callee
    side.
 
    Default value is "callee_cseq".
 
-   Example 1.19. Set callee_cseq_column parameter
+   Example 1.20. Set callee_cseq_column parameter
 ...
 modparam("dialog", "callee_cseq_column", "column_name")
 ...
 
-1.5.20. caller_route_column (string)
+1.5.21. caller_route_column (string)
 
    The column's name in the database to store the route records
    from caller side (proxy to caller).
 
    Default value is "caller_route_set".
 
-   Example 1.20. Set caller_route_column parameter
+   Example 1.21. Set caller_route_column parameter
 ...
 modparam("dialog", "caller_route_column", "column_name")
 ...
 
-1.5.21. callee_route_column (string)
+1.5.22. callee_route_column (string)
 
    The column's name in the database to store the route records
    from callee side (proxy to callee).
 
    Default value is "callee_route_set".
 
-   Example 1.21. Set to_route_column parameter
+   Example 1.22. Set to_route_column parameter
 ...
 modparam("dialog", "to_route_column", "column_name")
 ...
 
-1.5.22. caller_contact_column (string)
+1.5.23. caller_contact_column (string)
 
    The column's name in the database to store the caller's contact
    uri.
 
    Default value is "from_contact".
 
-   Example 1.22. Set caller_contact_column parameter
+   Example 1.23. Set caller_contact_column parameter
 ...
 modparam("dialog", "caller_contact_column", "column_name")
 ...
 
-1.5.23. callee_contact_column (string)
+1.5.24. callee_contact_column (string)
 
    The column's name in the database to store the callee's contact
    uri.
 
    Default value is "callee_contact".
 
-   Example 1.23. Set callee_contact_column parameter
+   Example 1.24. Set callee_contact_column parameter
 ...
 modparam("dialog", "callee_contact_column", "column_name")
 ...
 
-1.5.24. caller_sock_column (string)
+1.5.25. caller_sock_column (string)
 
    The column's name in the database to store the information
    about the local interface receiving the traffic from caller.
 
    Default value is "caller_sock".
 
-   Example 1.24. Set caller_sock_column parameter
+   Example 1.25. Set caller_sock_column parameter
 ...
 modparam("dialog", "caller_sock_column", "column_name")
 ...
 
-1.5.25. callee_sock_column (string)
+1.5.26. callee_sock_column (string)
 
    The column's name in the database to store information about
    the local interface receiving the traffic from callee.
 
    Default value is "callee_contact".
 
-   Example 1.25. Set callee_sock_column parameter
+   Example 1.26. Set callee_sock_column parameter
 ...
 modparam("dialog", "callee_sock_column", "column_name")
 ...
 
-1.5.26. h_id_column (string)
+1.5.27. h_id_column (string)
 
    The column's name in the database to store the dialogs' hash id
    information.
 
    Default value is "hash_id".
 
-   Example 1.26. Set h_id_column parameter
+   Example 1.27. Set h_id_column parameter
 ...
 modparam("dialog", "h_id_column", "hash_id_c_name")
 ...
 
-1.5.27. h_entry_column (string)
+1.5.28. h_entry_column (string)
 
    The column's name in the database to store the dialogs' hash
    entry information.
 
    Default value is "hash_entry".
 
-   Example 1.27. Set h_entry_column parameter
+   Example 1.28. Set h_entry_column parameter
 ...
 modparam("dialog", "h_entry_column", "h_entry_c_name")
 ...
 
-1.5.28. state_column (string)
+1.5.29. state_column (string)
 
    The column's name in the database to store the dialogs' state
    information.
 
    Default value is "state".
 
-   Example 1.28. Set state_column parameter
+   Example 1.29. Set state_column parameter
 ...
 modparam("dialog", "state_column", "state_c_name")
 ...
 
-1.5.29. start_time_column (string)
+1.5.30. start_time_column (string)
 
    The column's name in the database to store the dialogs' start
    time information.
 
    Default value is "start_time".
 
-   Example 1.29. Set start_time_column parameter
+   Example 1.30. Set start_time_column parameter
 ...
 modparam("dialog", "start_time_column", "start_time_c_name")
 ...
 
-1.5.30. timeout_column (string)
+1.5.31. timeout_column (string)
 
    The column's name in the database to store the dialogs'
    timeout.
 
    Default value is "timeout".
 
-   Example 1.30. Set timeout_column parameter
+   Example 1.31. Set timeout_column parameter
 ...
 modparam("dialog", "timeout_column", "timeout_c_name")
 ...
 
-1.5.31. profiles_with_value (string)
+1.5.32. profiles_with_value (string)
 
    List of names for profiles with values.
 
    Default value is "empty".
 
-   Example 1.31. Set profiles_with_value parameter
+   Example 1.32. Set profiles_with_value parameter
 ...
 modparam("dialog", "profiles_with_value", "caller ; my_profile")
 ...
 
-1.5.32. profiles_no_value (string)
+1.5.33. profiles_no_value (string)
 
    List of names for profiles without values.
 
    Default value is "empty".
 
-   Example 1.32. Set profiles_no_value parameter
+   Example 1.33. Set profiles_no_value parameter
 ...
 modparam("dialog", "profiles_no_value", "inbound ; outbound")
 ...
@@ -637,7 +655,7 @@ modparam("dialog", "profiles_no_value", "inbound ; outbound")
    This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
    REPLY_ROUTE and FAILURE_ROUTE.
 
-   Example 1.33. set_dlg_profile usage
+   Example 1.34. set_dlg_profile usage
 ...
 set_dlg_profile("inbound_call");
 set_dlg_profile("caller","$fu");
@@ -661,7 +679,7 @@ set_dlg_profile("caller","$fu");
    This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
    REPLY_ROUTE and FAILURE_ROUTE.
 
-   Example 1.34. is_in_profile usage
+   Example 1.35. is_in_profile usage
 ...
 if (is_in_profile("inbound_call")) {
         log("this request belongs to a inbound call\n");
@@ -692,7 +710,7 @@ if (is_in_profile("caller","XX")) {
    This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
    REPLY_ROUTE and FAILURE_ROUTE.
 
-   Example 1.35. get_profile_size usage
+   Example 1.36. get_profile_size usage
 ...
 get_profile_size("inbound_call","$avp(size)");
 xlog("currently there are $avp(size) inbound calls\n");

+ 4 - 1
modules_k/dialog/dialog.c

@@ -81,6 +81,8 @@ static int seq_match_mode = SEQ_MATCH_STRICT_ID;
 static char* profiles_wv_s = NULL;
 static char* profiles_nv_s = NULL;
 str dlg_extra_hdrs = {NULL,0};
+static int db_fetch_rows = 200;
+
 
 /* statistic variables */
 int dlg_enable_stats = 1;
@@ -158,6 +160,7 @@ static param_export_t mod_params[]={
 	{ "to_sock_column",        STR_PARAM, &to_sock_column.s         },
 	{ "from_sock_column",      STR_PARAM, &from_sock_column.s       },
 	{ "db_update_period",      INT_PARAM, &db_update_period         },
+	{ "db_fetch_rows",         INT_PARAM, &db_fetch_rows            },
 	{ "profiles_with_value",   STR_PARAM, &profiles_wv_s            },
 	{ "profiles_no_value",     STR_PARAM, &profiles_nv_s            },
 	{ 0,0,0 }
@@ -469,7 +472,7 @@ static int mod_init(void)
 			LM_ERR("db_url not configured for db_mode %d\n", dlg_db_mode);
 			return -1;
 		}
-		if (init_dlg_db(&db_url, dlg_hash_size, db_update_period)!=0) {
+		if (init_dlg_db(&db_url, dlg_hash_size, db_update_period,db_fetch_rows)!=0) {
 			LM_ERR("failed to initialize the DB support\n");
 			return -1;
 		}

+ 116 - 101
modules_k/dialog/dlg_db_handler.c

@@ -105,7 +105,7 @@ extern stat_var *early_dlgs;
 	}while(0);
 
 
-static int load_dialog_info_from_db(int dlg_hash_size);
+static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows);
 
 
 int dlg_connect_db(const str *db_url)
@@ -120,7 +120,7 @@ int dlg_connect_db(const str *db_url)
 }
 
 
-int init_dlg_db(const str *db_url, int dlg_hash_size , int db_update_period)
+int init_dlg_db(const str *db_url, int dlg_hash_size , int db_update_period, int fetch_num_rows)
 {
 	/* Find a database module */
 	if (db_bind_mod(db_url, &dialog_dbf) < 0){
@@ -144,7 +144,7 @@ int init_dlg_db(const str *db_url, int dlg_hash_size , int db_update_period)
 		return -1;
 	}
 
-	if( (load_dialog_info_from_db(dlg_hash_size) ) !=0 ){
+	if( (load_dialog_info_from_db(dlg_hash_size, fetch_num_rows) ) !=0 ){
 		LM_ERR("unable to load the dialog data\n");
 		return -1;
 	}
@@ -185,7 +185,7 @@ static int use_dialog_table(void)
 
 
 
-static int select_entire_dialog_table(db_res_t ** res)
+static int select_entire_dialog_table(db_res_t ** res, int fetch_num_rows)
 {
 	db_key_t query_cols[DIALOG_TABLE_COL_NO] = {	&h_entry_column,
 			&h_id_column,		&call_id_column,	&from_uri_column,
@@ -200,10 +200,22 @@ static int select_entire_dialog_table(db_res_t ** res)
 	}
 
 	/*select the whole tabel and all the columns*/
-	if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0, 
-	DIALOG_TABLE_COL_NO, 0, res) < 0) {
-		LM_ERR("Error while querying database\n");
-		return -1;
+	if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) {
+		if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0, 
+				DIALOG_TABLE_COL_NO, 0, 0) < 0) {
+			LM_ERR("Error while querying database\n");
+			return -1;
+		}
+		if(dialog_dbf.fetch_result(dialog_db_handle, res, fetch_num_rows) < 0) {
+			LM_ERR("fetching rows failed\n");
+			return -1;
+		}
+	} else {
+		if(dialog_dbf.query(dialog_db_handle,0,0,0,query_cols, 0, 
+				DIALOG_TABLE_COL_NO, 0, res) < 0) {
+			LM_ERR("Error while querying database\n");
+			return -1;
+		}
 	}
 
 	return 0;
@@ -240,7 +252,7 @@ struct socket_info * create_socket_info(db_val_t * vals, int n){
 
 
 
-static int load_dialog_info_from_db(int dlg_hash_size)
+static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
 {
 	db_res_t * res;
 	db_val_t * values;
@@ -253,7 +265,7 @@ static int load_dialog_info_from_db(int dlg_hash_size)
 	
 
 	res = 0;
-	if((nr_rows = select_entire_dialog_table(&res)) < 0)
+	if((nr_rows = select_entire_dialog_table(&res, fetch_num_rows)) < 0)
 		goto end;
 
 	nr_rows = RES_ROW_N(res);
@@ -263,100 +275,103 @@ static int load_dialog_info_from_db(int dlg_hash_size)
 	rows = RES_ROWS(res);
 	
 	/*for every row---dialog*/
-	for(i=0; i<nr_rows; i++){
-
-		values = ROW_VALUES(rows + i);
-
-		if (VAL_NULL(values) || VAL_NULL(values+1)) {
-			LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
-				h_entry_column.len, h_entry_column.s,
-				h_id_column.len, h_id_column.s);
-			continue;
-		}
-
-		if (VAL_NULL(values+7) || VAL_NULL(values+8)) {
-			LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
-				start_time_column.len, start_time_column.s,
-				state_column.len, state_column.s);
-			continue;
-		}
-
-		/*restore the dialog info*/
-		GET_STR_VALUE(callid, values, 2, 1, 0);
-		GET_STR_VALUE(from_uri, values, 3, 1, 0);
-		GET_STR_VALUE(from_tag, values, 4, 1, 0);
-		GET_STR_VALUE(to_uri, values, 5, 1, 0);
-
-		if((dlg=build_new_dlg( &callid, &from_uri, &to_uri, &from_tag))==0){
-			LM_ERR("failed to build new dialog\n");
-			goto error;
-		}
-
-		if(dlg->h_entry != VAL_INT(values)){
-			LM_ERR("inconsistent hash data in the dialog database: "
-				"you may have restarted openser using a different hash_size:"
-				"please erase %.*s database and restart\n", 
-				dialog_table_name.len, dialog_table_name.s);
-			shm_free(dlg);
-			goto error;
-		}
-
-		/*link the dialog*/
-		link_dlg(dlg, 0);
-
-		dlg->h_id = VAL_INT(values+1);
-		next_id = d_table->entries[dlg->h_entry].next_id;
-
-		d_table->entries[dlg->h_entry].next_id =
-			(next_id < dlg->h_id) ? (dlg->h_id+1) : next_id;
-
-		GET_STR_VALUE(to_tag, values, 6, 1, 1);
-
-		dlg->start_ts	= VAL_INT(values+7);
-
-		dlg->state 		= VAL_INT(values+8);
-		if (dlg->state==DLG_STATE_CONFIRMED_NA ||
-		dlg->state==DLG_STATE_CONFIRMED) {
-			if_update_stat(dlg_enable_stats, active_dlgs, 1);
-		} else if (dlg->state==DLG_STATE_EARLY) {
-			if_update_stat(dlg_enable_stats, early_dlgs, 1);
-		}
-
-		dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks();
-		if (dlg->tl.timeout<=(unsigned int)time(0))
-			dlg->tl.timeout = 0;
-		else
-			dlg->tl.timeout -= (unsigned int)time(0);
-
-		/*restore the timer values */
-		insert_dlg_timer(&(dlg->tl), (int)dlg->tl.timeout);
-		LM_DBG("current dialog timeout is %u\n", dlg->tl.timeout);
-
-		GET_STR_VALUE(cseq1, values, 10 , 1, 1);
-		GET_STR_VALUE(cseq2, values, 11 , 1, 1);
-		GET_STR_VALUE(rroute1, values, 12, 0, 0);
-		GET_STR_VALUE(rroute2, values, 13, 0, 0);
-		GET_STR_VALUE(contact1, values, 14, 1, 1);
-		GET_STR_VALUE(contact2, values, 15, 1, 1);
-
-		if ( (dlg_set_leg_info( dlg, &from_tag, &rroute1, &contact1,
-		&cseq1, DLG_CALLER_LEG)!=0) ||
-		(dlg_set_leg_info( dlg, &to_tag, &rroute2, &contact2,
-		&cseq2, DLG_CALLEE_LEG)!=0) ) {
-			LM_ERR("dlg_set_leg_info failed\n");
-			unref_dlg(dlg,1);
-			continue;
-		}
 
-		dlg->bind_addr[DLG_CALLER_LEG] = create_socket_info(values, 16);
-		dlg->bind_addr[DLG_CALLEE_LEG] = create_socket_info(values, 17);
+	do {
+		for(i=0; i<nr_rows; i++){
+	
+			values = ROW_VALUES(rows + i);
+	
+			if (VAL_NULL(values) || VAL_NULL(values+1)) {
+				LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
+					h_entry_column.len, h_entry_column.s,
+					h_id_column.len, h_id_column.s);
+				continue;
+			}
+	
+			if (VAL_NULL(values+7) || VAL_NULL(values+8)) {
+				LM_ERR("columns %.*s or/and %.*s cannot be null -> skipping\n",
+					start_time_column.len, start_time_column.s,
+					state_column.len, state_column.s);
+				continue;
+			}
+	
+			/*restore the dialog info*/
+			GET_STR_VALUE(callid, values, 2, 1, 0);
+			GET_STR_VALUE(from_uri, values, 3, 1, 0);
+			GET_STR_VALUE(from_tag, values, 4, 1, 0);
+			GET_STR_VALUE(to_uri, values, 5, 1, 0);
+	
+			if((dlg=build_new_dlg( &callid, &from_uri, &to_uri, &from_tag))==0){
+				LM_ERR("failed to build new dialog\n");
+				goto error;
+			}
+	
+			if(dlg->h_entry != VAL_INT(values)){
+				LM_ERR("inconsistent hash data in the dialog database: "
+					"you may have restarted openser using a different hash_size:"
+					"please erase %.*s database and restart\n", 
+					dialog_table_name.len, dialog_table_name.s);
+				shm_free(dlg);
+				goto error;
+			}
+	
+			/*link the dialog*/
+			link_dlg(dlg, 0);
+	
+			dlg->h_id = VAL_INT(values+1);
+			next_id = d_table->entries[dlg->h_entry].next_id;
 	
-		dlg->lifetime = 0;
-		dlg->flags = 0;
+			d_table->entries[dlg->h_entry].next_id =
+				(next_id < dlg->h_id) ? dlg->h_id : next_id;
+	
+			GET_STR_VALUE(to_tag, values, 6, 1, 1);
+	
+			dlg->start_ts	= VAL_INT(values+7);
+			dlg->state 		= VAL_INT(values+8);
+			dlg->tl.timeout = (unsigned int)(VAL_INT(values+9)) + get_ticks();
+			if (dlg->tl.timeout<=(unsigned int)time(0))
+				dlg->tl.timeout = 0;
+			else
+				dlg->tl.timeout -= (unsigned int)time(0);
+	
+			/*restore the timer values */
+			insert_dlg_timer(&(dlg->tl), (int)dlg->tl.timeout);
+			LM_DBG("current dialog timeout is %u\n", dlg->tl.timeout);
+	
+			GET_STR_VALUE(cseq1, values, 10 , 1, 1);
+			GET_STR_VALUE(cseq2, values, 11 , 1, 1);
+			GET_STR_VALUE(rroute1, values, 12, 0, 0);
+			GET_STR_VALUE(rroute2, values, 13, 0, 0);
+			GET_STR_VALUE(contact1, values, 14, 1, 1);
+			GET_STR_VALUE(contact2, values, 15, 1, 1);
+	
+			if ( (dlg_set_leg_info( dlg, &from_tag, &rroute1, &contact1,
+			&cseq1, DLG_CALLER_LEG)!=0) ||
+			(dlg_set_leg_info( dlg, &to_tag, &rroute2, &contact2,
+			&cseq2, DLG_CALLEE_LEG)!=0) ) {
+				LM_ERR("dlg_set_leg_info failed\n");
+				unref_dlg(dlg,1);
+				continue;
+			}
+	
+			dlg->bind_addr[DLG_CALLER_LEG] = create_socket_info(values, 16);
+			dlg->bind_addr[DLG_CALLEE_LEG] = create_socket_info(values, 17);
+		
+			dlg->lifetime = 0;
+			dlg->flags = 0;
 next_dialog:
-		;
-	}
-
+			;
+ 		}
+		if (DB_CAPABILITY(dialog_dbf, DB_CAP_FETCH) && (fetch_num_rows > 0)) {
+			if(dialog_dbf.fetch_result(dialog_db_handle, &res, fetch_num_rows) < 0) {
+				LM_ERR("fetching rows failed\n");
+				goto error;
+			}
+			nr_rows = RES_ROW_N(res);			
+		} else {
+			nr_rows = 0;
+		}
+	} while (nr_rows > 0);
 end:
 	dialog_dbf.free_result(dialog_db_handle, res);
 	return 0;

+ 1 - 1
modules_k/dialog/dlg_db_handler.h

@@ -84,7 +84,7 @@ extern str from_sock_column;
 extern str dialog_table_name;
 extern int dlg_db_mode;
 
-int init_dlg_db(const str *db_url, int dlg_hash_size, int db_update_period);
+int init_dlg_db(const str *db_url, int dlg_hash_size, int db_update_period, int fetch_num_rows);
 int dlg_connect_db(const str *db_url);
 void destroy_dlg_db();
 

+ 22 - 0
modules_k/dialog/doc/dialog_admin.xml

@@ -395,6 +395,28 @@ modparam("dialog", "db_mode", 1)
 ...
 modparam("dialog", "db_update_period", 120)
 ...
+</programlisting>
+		</example>
+	</section>
+
+<section>
+		<title><varname>db_fetch_rows</varname> (integer)</title>
+		<para>
+			The number of the rows to be fetched at once from database when loading the dialog records at startup from the database.
+			This value can be used to tune the load time at startup. For 1MB of private memory (default) it should be below 400.
+			The database driver must support fetch_result() capability. A value of 0 means the functionality is disabled.
+		</para>
+		<para>
+		<emphasis>
+			Default value is <quote>200</quote>.
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>db_fetch_rows</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("dialog", "db_fetch_rows", 500)
+...
 </programlisting>
 		</example>
 	</section>