Parcourir la 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 il y a 13 ans
Parent
commit
6d7e23db56
5 fichiers modifiés avec 321 ajouts et 619 suppressions
  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;

Fichier diff supprimé car celui-ci est trop grand
+ 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;

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff