Prechádzať zdrojové kódy

dispatcher: use avl-tree for ds_set indexing

Alekzander Spiridonov 9 rokov pred
rodič
commit
996f50eb2c

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 370 - 336
modules/dispatcher/dispatch.c


+ 11 - 2
modules/dispatcher/dispatch.h

@@ -114,7 +114,7 @@ int ds_reinit_state(int group, str *address, int state);
 int ds_mark_dst(struct sip_msg *msg, int mode);
 int ds_print_list(FILE *fout);
 int ds_print_mi_list(struct mi_node* rpl);
-int ds_print_sets(void);
+int ds_log_sets(void);
 int ds_list_exist(int set);
 
 
@@ -178,8 +178,13 @@ typedef struct _ds_set
 	ds_dest_t *dlist;
 	unsigned int wlist[100];
 	unsigned int rwlist[100];
-	struct _ds_set *next;
+	struct _ds_set *next[2];
+	int longer:2;
 } ds_set_t;
+#define AVL_LEFT 0
+#define AVL_RIGHT 1
+#define AVL_NEITHER -1
+#define AVL_BALANCED(n) (n->longer < 0)
 
 ds_set_t *ds_get_list(void);
 int ds_get_list_nr(void);
@@ -188,5 +193,9 @@ int ds_ping_active_init(void);
 int ds_ping_active_get(void);
 int ds_ping_active_set(int v);
 
+ds_set_t* ds_avl_insert( ds_set_t** root, int id, int* setn ); /// Create if not exist and return ds_set_t by id
+ds_set_t* ds_avl_find( ds_set_t* node, int id );
+void ds_avl_destroy( ds_set_t** node );
+
 #endif
 

+ 115 - 100
modules/dispatcher/dispatcher.c

@@ -72,13 +72,13 @@ char *dslistfile = CFG_DIR"dispatcher.list";
 int  ds_force_dst   = 1;
 int  ds_flags       = 0;
 int  ds_use_default = 0;
-static str dst_avp_param = {NULL, 0};
-static str grp_avp_param = {NULL, 0};
-static str cnt_avp_param = {NULL, 0};
-static str dstid_avp_param = {NULL, 0};
-static str attrs_avp_param = {NULL, 0};
-static str sock_avp_param = {NULL, 0};
-str hash_pvar_param = {NULL, 0};
+static str dst_avp_param = STR_NULL;
+static str grp_avp_param = STR_NULL;
+static str cnt_avp_param = STR_NULL;
+static str dstid_avp_param = STR_NULL;
+static str attrs_avp_param = STR_NULL;
+static str sock_avp_param = STR_NULL;
+str hash_pvar_param = STR_NULL;
 
 int_str dst_avp_name;
 unsigned short dst_avp_type;
@@ -104,11 +104,11 @@ str ds_ping_from   = str_init("sip:dispatcher@localhost");
 static int ds_ping_interval = 0;
 int ds_probing_mode  = DS_PROBE_NONE;
 
-static str ds_ping_reply_codes_str= {NULL, 0};
+static str ds_ping_reply_codes_str= STR_NULL;
 static int** ds_ping_reply_codes = NULL;
 static int* ds_ping_reply_codes_cnt;
 
-str ds_default_socket       = {NULL, 0};
+str ds_default_socket       = STR_NULL;
 struct socket_info * ds_default_sockinfo = NULL;
 
 int ds_hash_size = 0;
@@ -117,13 +117,13 @@ int ds_hash_initexpire = 7200;
 int ds_hash_check_interval = 30;
 int ds_timer_mode = 0;
 
-str ds_outbound_proxy = {0, 0};
+str ds_outbound_proxy = STR_NULL;
 
 /* tm */
 struct tm_binds tmb;
 
 /*db */
-str ds_db_url            = {NULL, 0};
+str ds_db_url            = STR_NULL;
 str ds_set_id_col        = str_init(DS_SET_ID_COL);
 str ds_dest_uri_col      = str_init(DS_DEST_URI_COL);
 str ds_dest_flags_col    = str_init(DS_DEST_FLAGS_COL);
@@ -131,9 +131,9 @@ str ds_dest_priority_col = str_init(DS_DEST_PRIORITY_COL);
 str ds_dest_attrs_col    = str_init(DS_DEST_ATTRS_COL);
 str ds_table_name        = str_init(DS_TABLE_NAME);
 
-str ds_setid_pvname   = {NULL, 0};
+str ds_setid_pvname   = STR_NULL;
 pv_spec_t ds_setid_pv;
-str ds_attrs_pvname   = {NULL, 0};
+str ds_attrs_pvname   = STR_NULL;
 pv_spec_t ds_attrs_pv;
 
 /** module functions */
@@ -1170,27 +1170,116 @@ static const char* dispatcher_rpc_list_doc[2] = {
 	0
 };
 
-
-/*
- * RPC command to print dispatcher destination sets
+/**
+ *
  */
-static void dispatcher_rpc_list(rpc_t* rpc, void* ctx)
+int ds_rpc_print_set( ds_set_t* node, rpc_t* rpc, void* ctx, void* rpc_handle )
 {
-	void* th;
-	void* ih;
+	if ( !node )
+		return 0;
+
+	int i=0, rc=0;
+	for( ;i<2;++i)
+	{
+		rc = ds_rpc_print_set( node->next[i], rpc, ctx, rpc_handle );
+		if ( rc != 0 )
+			return rc;
+	}
+
 	void* rh;
 	void* sh;
 	void* vh;
 	void* wh;
 	int j;
 	char c[3];
-	str data = {"", 0};
-	ds_set_t *ds_list;
-	int ds_list_nr;
-	ds_set_t *list;
+	str data = STR_NULL;
+
+	if (rpc->struct_add(rpc_handle, "{", "SET", &sh) < 0)
+	{
+		rpc->fault(ctx, 500, "Internal error set structure");
+		return -1;
+	}
+	if(rpc->struct_add(sh, "d[",
+				"ID", node->id,
+				"TARGETS", &rh)<0)
+	{
+		rpc->fault(ctx, 500, "Internal error creating set id");
+		return -1;
+	}
+
+	for(j=0; j<node->nr; j++)
+	{
+		if(rpc->struct_add(rh, "{",
+					"DEST", &vh)<0)
+		{
+			rpc->fault(ctx, 500, "Internal error creating dest");
+			return -1;
+		}
+
+		memset(&c, 0, sizeof(c));
+		if (node->dlist[j].flags & DS_INACTIVE_DST)
+			c[0] = 'I';
+		else if (node->dlist[j].flags & DS_DISABLED_DST)
+			c[0] = 'D';
+		else if (node->dlist[j].flags & DS_TRYING_DST)
+			c[0] = 'T';
+		else
+			c[0] = 'A';
+
+		if (node->dlist[j].flags & DS_PROBING_DST)
+			c[1] = 'P';
+		else
+			c[1] = 'X';
+
+		if (node->dlist[j].attrs.body.s)
+		{
+			if(rpc->struct_add(vh, "Ssd{",
+						"URI", &node->dlist[j].uri,
+						"FLAGS", c,
+						"PRIORITY", node->dlist[j].priority,
+						"ATTRS", &wh)<0)
+			{
+				rpc->fault(ctx, 500, "Internal error creating dest struct");
+				return -1;
+			}
+			if(rpc->struct_add(wh, "SSdddS",
+						"BODY", &(node->dlist[j].attrs.body),
+						"DUID", (node->dlist[j].attrs.duid.s)?
+						&(node->dlist[j].attrs.duid):&data,
+						"MAXLOAD", node->dlist[j].attrs.maxload,
+						"WEIGHT", node->dlist[j].attrs.weight,
+						"RWEIGHT", node->dlist[j].attrs.rweight,
+						"SOCKET", (node->dlist[j].attrs.socket.s)?
+						&(node->dlist[j].attrs.socket):&data)<0)
+			{
+				rpc->fault(ctx, 500, "Internal error creating attrs struct");
+				return -1;
+			}
+		} else {
+			if(rpc->struct_add(vh, "Ssd",
+						"URI", &node->dlist[j].uri,
+						"FLAGS", c,
+						"PRIORITY", node->dlist[j].priority)<0)
+			{
+				rpc->fault(ctx, 500, "Internal error creating dest struct");
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * RPC command to print dispatcher destination sets
+ */
+static void dispatcher_rpc_list(rpc_t* rpc, void* ctx)
+{
+	void* th;
+	void* ih;
 
-	ds_list = ds_get_list();
-	ds_list_nr = ds_get_list_nr();
+	ds_set_t *ds_list = ds_get_list();
+	int ds_list_nr = ds_get_list_nr();
 
 	if(ds_list==NULL || ds_list_nr<=0)
 	{
@@ -1213,81 +1302,7 @@ static void dispatcher_rpc_list(rpc_t* rpc, void* ctx)
 		return;
 	}
 
-	for(list = ds_list; list!= NULL; list= list->next)
-	{
-		if (rpc->struct_add(ih, "{", "SET", &sh) < 0)
-		{
-			rpc->fault(ctx, 500, "Internal error set structure");
-			return;
-		}
-		if(rpc->struct_add(sh, "d[",
-					"ID", list->id,
-					"TARGETS", &rh)<0)
-		{
-			rpc->fault(ctx, 500, "Internal error creating set id");
-			return;
-		}
-
-		for(j=0; j<list->nr; j++)
-		{
-			if(rpc->struct_add(rh, "{",
-						"DEST", &vh)<0)
-			{
-				rpc->fault(ctx, 500, "Internal error creating dest");
-				return;
-			}
-
-			memset(&c, 0, sizeof(c));
-			if (list->dlist[j].flags & DS_INACTIVE_DST)
-				c[0] = 'I';
-			else if (list->dlist[j].flags & DS_DISABLED_DST)
-				c[0] = 'D';
-			else if (list->dlist[j].flags & DS_TRYING_DST)
-				c[0] = 'T';
-			else
-				c[0] = 'A';
-
-			if (list->dlist[j].flags & DS_PROBING_DST)
-				c[1] = 'P';
-			else
-				c[1] = 'X';
-
-			if (list->dlist[j].attrs.body.s)
-			{
-				if(rpc->struct_add(vh, "Ssd{",
-							"URI", &list->dlist[j].uri,
-							"FLAGS", c,
-							"PRIORITY", list->dlist[j].priority,
-							"ATTRS", &wh)<0)
-				{
-					rpc->fault(ctx, 500, "Internal error creating dest struct");
-					return;
-				}
-				if(rpc->struct_add(wh, "SSdddS",
-							"BODY", &(list->dlist[j].attrs.body),
-							"DUID", (list->dlist[j].attrs.duid.s)?
-							&(list->dlist[j].attrs.duid):&data,
-							"MAXLOAD", list->dlist[j].attrs.maxload,
-							"WEIGHT", list->dlist[j].attrs.weight,
-							"RWEIGHT", list->dlist[j].attrs.rweight,
-							"SOCKET", (list->dlist[j].attrs.socket.s)?
-							&(list->dlist[j].attrs.socket):&data)<0)
-				{
-					rpc->fault(ctx, 500, "Internal error creating attrs struct");
-					return;
-				}
-			} else {
-				if(rpc->struct_add(vh, "Ssd",
-							"URI", &list->dlist[j].uri,
-							"FLAGS", c,
-							"PRIORITY", list->dlist[j].priority)<0)
-				{
-					rpc->fault(ctx, 500, "Internal error creating dest struct");
-					return;
-				}
-			}
-		}
-	}
+	ds_rpc_print_set( ds_list, rpc, ctx, ih );
 
 	return;
 }

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov