Browse Source

modules_k/rls: RLS DB-only mode performance improvements

- When the RLS DB-only mode was implemented it was designed to do
  (as close as possible) exactly what the hash-table mode did in
  the same way the hash-table mode did it.

  This means lots of hash-table lookups (which are fast) result in
  lots of DB selects (which are slow).  It also means where an entry
  is found in the hash-table and modified in place, in DB mode a
  select must be done and then an update.

  A lot of these DB transactions are not strictly necessary, and
  often fields were retrieved or updated in the DB even when they
  hadn't changed.
- This change refactors the DB-only code (in rls_db.c) and
  re-orders the functional code in other files to make the DB
  operations as simple as possible and as few as few as possible.
Peter Dunkley 13 years ago
parent
commit
6d7e23db56
5 changed files with 321 additions and 619 deletions
  1. 3 3
      modules_k/rls/notify.c
  2. 15 19
      modules_k/rls/resource_notify.c
  3. 8 9
      modules_k/rls/rls.h
  4. 214 520
      modules_k/rls/rls_db.c
  5. 81 68
      modules_k/rls/subscribe.c

+ 3 - 3
modules_k/rls/notify.c

@@ -88,8 +88,8 @@ int send_full_notify(subs_t* subs, xmlNodePtr rl_node, str* rl_uri,
 {
 	xmlDocPtr rlmi_body= NULL;
 	xmlNodePtr list_node= NULL;
-	db_key_t query_cols[2], update_cols[2], result_cols[7];
-	db_val_t query_vals[2], update_vals[2];
+	db_key_t query_cols[1], update_cols[1], result_cols[5];
+	db_val_t query_vals[1], update_vals[1];
 	db1_res_t *result= NULL;
 	int n_result_cols= 0;
 	char* boundary_string;
@@ -349,7 +349,7 @@ int agg_body_sendn_update(str* rl_uri, char* boundary_string, str* rlmi_body,
 
 	if (dbmode==RLS_DB_ONLY)
 	{
-		if ( update_rlsdb(subs, LOCAL_TYPE) <0 )
+		if (update_dialog_notify_rlsdb(subs) < 0)
 		{
 			LM_ERR( "updating DB\n" );
 			goto error;

+ 15 - 19
modules_k/rls/resource_notify.c

@@ -85,22 +85,22 @@ int parse_rlsubs_did(char* str_did, str* callid, str* from_tag, str* to_tag)
 
 void get_dialog_from_did(char* did, subs_t **dialog, unsigned int *hash_code)
 {
-    str callid, to_tag, from_tag;
-    subs_t* s;
-    
-    *dialog= NULL;
+	str callid, to_tag, from_tag;
+	subs_t* s;
 
-    /* search the subscription in rlsubs_table*/		
-    if( parse_rlsubs_did(did, &callid, &from_tag, &to_tag)< 0)
+	*dialog= NULL;
+
+	/* search the subscription in rlsubs_table*/		
+	if( parse_rlsubs_did(did, &callid, &from_tag, &to_tag)< 0)
 	{
-        LM_ERR("bad format for "
-            "resource list Subscribe dialog indentifier(rlsubs did)\n");
-        return;
+		LM_ERR("bad format for resource list Subscribe dialog "
+			"indentifier(rlsubs did)\n");
+		return;
 	}
 
 	if (dbmode == RLS_DB_ONLY)
 	{
-		*dialog = get_dialog_rlsdb(callid,to_tag,from_tag);
+		*dialog = get_dialog_notify_rlsdb(callid,to_tag,from_tag);
 
 		if(*dialog==NULL)
 		{
@@ -131,10 +131,6 @@ void get_dialog_from_did(char* did, subs_t **dialog, unsigned int *hash_code)
 	{
 		LM_ERR("while copying subs_t structure\n");
 	}
-	else
-	{
-		dump_dialog( *dialog );
-	}
 
 	if (dbmode != RLS_DB_ONLY)
 		lock_release(&rls_table[*hash_code].lock);
@@ -825,8 +821,8 @@ error:
 
 void timer_send_notify(unsigned int ticks,void *param)
 {
-	db_key_t query_cols[2], update_cols[1], result_cols[7];
-	db_val_t query_vals[2], update_vals[1];
+	db_key_t query_cols[1], update_cols[1], result_cols[6];
+	db_val_t query_vals[1], update_vals[1];
 	int did_col, resource_uri_col, auth_state_col, reason_col,
 		pres_state_col, content_type_col;
 	int n_result_cols= 0;
@@ -888,9 +884,9 @@ done:
 
 void rls_presentity_clean(unsigned int ticks,void *param)
 {
-	db_key_t query_cols[2];
-	db_op_t query_ops[2];
-	db_val_t query_vals[2];
+	db_key_t query_cols[1];
+	db_op_t query_ops[1];
+	db_val_t query_vals[1];
 
 	query_cols[0]= &str_expires_col;
 	query_ops[0]= OP_LT;

+ 8 - 9
modules_k/rls/rls.h

@@ -153,15 +153,14 @@ extern xcap_nodeSel_add_terminal_t xcap_AddTerminal;
 extern xcap_nodeSel_free_t xcap_FreeNodeSel;
 
 /* rlsdb functions*/
-int delete_expired_subs_rlsdb( void );
-void dump_dialog( subs_t *s );
-extern int delete_rlsdb( str *callid, str *to_tag, str *from_tag );
-extern int update_rlsdb( subs_t *s, int type );
-extern int update_subs_rlsdb( subs_t *s );
-extern int insert_rlsdb( subs_t *s );
-extern int matches_in_rlsdb( str callid, str to_tag, str from_tag );
-extern int update_all_subs_rlsdb( str *from_user, str *from_domain, str *evt );
-subs_t *get_dialog_rlsdb( str callid, str to_tag, str from_tag );
+int delete_expired_subs_rlsdb(void);
+extern int delete_rlsdb(str *callid, str *to_tag, str *from_tag);
+extern int update_dialog_notify_rlsdb(subs_t *s);
+extern int update_dialog_subscribe_rlsdb(subs_t *s);
+extern int insert_rlsdb(subs_t *s);
+extern int get_dialog_subscribe_rlsdb(subs_t *s);
+subs_t *get_dialog_notify_rlsdb(str callid, str to_tag, str from_tag);
+extern int update_all_subs_rlsdb(str *from_user, str *from_domain, str *evt);
 
 extern str str_rlsubs_did_col;
 extern str str_resource_uri_col;

File diff suppressed because it is too large
+ 214 - 520
modules_k/rls/rls_db.c


+ 81 - 68
modules_k/rls/subscribe.c

@@ -521,8 +521,18 @@ int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
 			break;
 		}
 		ev_param= ev_param->next;
-	}		
+	}
 
+	/* extract dialog information from message headers */
+	if(pres_extract_sdialog_info(&subs, msg, rls_max_expires,
+				&to_tag_gen, rls_server_address)<0)
+	{
+		LM_ERR("bad subscribe request\n");
+		goto error;
+	}
+
+	hash_code = core_hash(&subs.callid, &subs.to_tag, hash_size);
+	
 	if(get_to(msg)->tag_value.s==NULL || get_to(msg)->tag_value.len==0)
 	{ /* initial Subscribe */
 		/*verify if Request URI represents a list by asking xcap server*/	
@@ -532,8 +542,8 @@ int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
 			LM_ERR("while constructing uri from user and domain\n");
 			goto error;
 		}
-		if(rls_get_service_list(&subs.pres_uri, &(GET_FROM_PURI(msg)->user),
-					&(GET_FROM_PURI(msg)->host), &service_node, &doc)<0)
+		if(rls_get_service_list(&subs.pres_uri, &subs.from_user,
+					&subs.from_domain, &service_node, &doc)<0)
 		{
 			LM_ERR("while attepmting to get a resource list\n");
 			goto error;
@@ -545,54 +555,11 @@ int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
 					subs.pres_uri.len, subs.pres_uri.s);
 			goto forpresence;
 		}
-	} else {
-		/* search if a stored dialog */
-		if ( dbmode == RLS_DB_ONLY )
-		{
-			if (matches_in_rlsdb(msg->callid->body,get_to(msg)->tag_value,
-							 get_from(msg)->tag_value ) <= 0 )
-			{
-				LM_DBG("subscription dialog not found for <%.*s>\n",
-						get_from(msg)->uri.len, get_from(msg)->uri.s);
-				goto forpresence;
-			}
-		}
-		else
-		{
-			hash_code = core_hash(&msg->callid->body,
-					&get_to(msg)->tag_value, hash_size);
-			lock_get(&rls_table[hash_code].lock);
 
-			if(pres_search_shtable(rls_table, msg->callid->body,
-					get_to(msg)->tag_value, get_from(msg)->tag_value,
-					hash_code)==NULL)
-			{
-				lock_release(&rls_table[hash_code].lock);
-				LM_DBG("subscription dialog not found for <%.*s>\n",
-						get_from(msg)->uri.len, get_from(msg)->uri.s);
-				goto forpresence;
-			}
-			lock_release(&rls_table[hash_code].lock);
-		}
-	}
-
-	/* extract dialog information from message headers */
-	if(pres_extract_sdialog_info(&subs, msg, rls_max_expires,
-				&to_tag_gen, rls_server_address)<0)
-	{
-		LM_ERR("bad subscribe request\n");
-		goto error;
-	}
-
-	/* if correct reply with 200 OK */
-	if(reply_200(msg, &subs.local_contact, subs.expires)<0)
-		goto error;
-
-	if (dbmode != RLS_DB_ONLY)
-		hash_code = core_hash(&subs.callid, &subs.to_tag, hash_size);
+		/* if correct reply with 200 OK */
+		if(reply_200(msg, &subs.local_contact, subs.expires)<0)
+			goto error;
 
-	if(get_to(msg)->tag_value.s==NULL || get_to(msg)->tag_value.len==0)
-	{ /* initial subscribe */
 		subs.local_cseq = 0;
 
 		if(subs.expires != 0)
@@ -613,30 +580,77 @@ int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
 			}
 		}
 	} else {
-		if (dbmode==RLS_DB_ONLY)
+		/* search if a stored dialog */
+		if ( dbmode == RLS_DB_ONLY )
 		{
-			rt=update_subs_rlsdb( &subs );
+			rt = get_dialog_subscribe_rlsdb(&subs);
+
+			if (rt <= 0)
+			{
+				LM_DBG("subscription dialog not found for <%.*s@%.*s>\n",
+						subs.from_user.len, subs.from_user.s,
+						subs.from_domain.len, subs.from_domain.s);
+				goto forpresence;
+			}
+			else if(rt>=400)
+			{
+				reason = (rt==400)?pu_400_rpl:stale_cseq_rpl;
+		
+				if (slb.freply(msg, 400, &reason) < 0)
+				{
+					LM_ERR("while sending reply\n");
+					goto error;
+				}
+				return 0;
+			}
+
+			/* if correct reply with 200 OK */
+			if(reply_200(msg, &subs.local_contact, subs.expires)<0)
+				goto error;
+
+			if (update_dialog_subscribe_rlsdb(&subs) < 0)
+			{
+				LM_ERR("while updating resource list subscription\n");
+				goto error;
+			}
 		}
 		else
 		{
+			lock_get(&rls_table[hash_code].lock);
+			if(pres_search_shtable(rls_table, subs.callid,
+					subs.to_tag, subs.from_tag, hash_code)==NULL)
+			{
+				lock_release(&rls_table[hash_code].lock);
+				LM_DBG("subscription dialog not found for <%.*s@%.*s>\n",
+						subs.from_user.len, subs.from_user.s,
+						subs.from_domain.len, subs.from_domain.s);
+				goto forpresence;
+			}
+			lock_release(&rls_table[hash_code].lock);
+
+			/* if correct reply with 200 OK */
+			if(reply_200(msg, &subs.local_contact, subs.expires)<0)
+				goto error;
+
 			rt = update_rlsubs(&subs, hash_code);
-		}
-		if(rt<0)
-		{
-			LM_ERR("while updating resource list subscription\n");
-			goto error;
-		}
-	
-		if(rt>=400)
-		{
-			reason = (rt==400)?pu_400_rpl:stale_cseq_rpl;
-		
-			if (slb.freply(msg, 400, &reason) < 0)
+
+			if(rt<0)
 			{
-				LM_ERR("while sending reply\n");
+				LM_ERR("while updating resource list subscription\n");
 				goto error;
 			}
-			return 0;
+	
+			if(rt>=400)
+			{
+				reason = (rt==400)?pu_400_rpl:stale_cseq_rpl;
+		
+				if (slb.freply(msg, 400, &reason) < 0)
+				{
+					LM_ERR("while sending reply\n");
+					goto error;
+				}
+				return 0;
+			}
 		}	
 
 		if(rls_get_service_list(&subs.pres_uri, &subs.from_user,
@@ -671,7 +685,7 @@ int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
 	{
 		if(subs.expires==0)
 		{
-			delete_rlsdb( &subs.callid, &subs.to_tag, &subs.from_tag );
+			delete_rlsdb(&subs.callid, &subs.to_tag, &subs.from_tag);
 		}
 	}
 	else
@@ -1027,8 +1041,7 @@ int fixup_update_subs(void** param, int param_no)
 	return 0;
 }
 
-void update_a_sub(subs_t *subs_copy )
-
+void update_a_sub(subs_t *subs_copy)
 {
 	xmlDocPtr doc = NULL;
 	xmlNodePtr service_node = NULL;

Some files were not shown because too many files changed in this diff