Module: sip-router
Branch: master
Commit: dcd67373212fe0a7e3694931b548fa5ccdf31500
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=dcd6737…
Author: Juha Heinanen <jh(a)tutpro.com>
Committer: Juha Heinanen <jh(a)tutpro.com>
Date: Thu May 17 09:07:13 2012 +0300
modules/lcr: improved reloading speed of lcr_rule_target table
---
modules/lcr/hash.c | 71 ++++++++++++++++++++++++++++++++++++------------
modules/lcr/hash.h | 4 ++-
modules/lcr/lcr_mod.c | 21 +++++++++++++-
modules/lcr/lcr_mod.h | 9 +++++-
4 files changed, 83 insertions(+), 22 deletions(-)
diff --git a/modules/lcr/hash.c b/modules/lcr/hash.c
index bef23cb..5190830 100644
--- a/modules/lcr/hash.c
+++ b/modules/lcr/hash.c
@@ -1,7 +1,7 @@
/*
* Header file for hash table functions
*
- * Copyright (C) 2008-2009 Juha Heinanen
+ * Copyright (C) 2008-2012 Juha Heinanen
*
* This file is part of SIP Router, a free SIP server.
*
@@ -45,10 +45,11 @@ int rule_hash_table_insert(struct rule_info **hash_table,
struct rule_info *rule;
str prefix_str;
unsigned int hash_val;
+ struct rule_id_info *rid;
rule = (struct rule_info *)shm_malloc(sizeof(struct rule_info));
if (rule == NULL) {
- LM_ERR("Cannot allocate memory for rule hash table entry\n");
+ LM_ERR("no shm memory for rule hash table entry\n");
if (from_uri_re) shm_free(from_uri_re);
if (request_uri_re) shm_free(request_uri_re);
return 0;
@@ -82,10 +83,25 @@ int rule_hash_table_insert(struct rule_info **hash_table,
rule->next = hash_table[hash_val];
hash_table[hash_val] = rule;
- LM_DBG("inserted rule <%u>, prefix <%.*s>, from_uri <%.*s>,
request_uri <%.*s>, stopper <%u>, "
- "into index <%u>\n",
- rule_id, prefix_len, prefix, from_uri_len, from_uri, request_uri_len, request_uri,
stopper,
- hash_val);
+ LM_DBG("inserted rule_id <%u>, prefix <%.*s>, from_uri <%.*s>,
"
+ "request_uri <%.*s>, stopper <%u>, into index <%u>\n",
+ rule_id, prefix_len, prefix, from_uri_len, from_uri,
+ request_uri_len, request_uri, stopper, hash_val);
+
+ /* Add rule_id info to rule_id hash table */
+ rid = (struct rule_id_info *)pkg_malloc(sizeof(struct rule_id_info));
+ if (rid == NULL) {
+ LM_ERR("no pkg memory for rule_id hash table entry\n");
+ return 0;
+ }
+ memset(rid, 0, sizeof(struct rule_id_info));
+ rid->rule_id = rule_id;
+ rid->rule_addr = rule;
+ hash_val = rule_id % lcr_rule_hash_size_param;
+ rid->next = rule_id_hash_table[hash_val];
+ rule_id_hash_table[hash_val] = rid;
+ LM_DBG("inserted rule_id <%u> addr <%p> into rule_id hash table
"
+ "index <%u>\n", rule_id, rule, hash_val);
return 1;
}
@@ -115,10 +131,9 @@ int rule_hash_table_insert_target(struct rule_info **hash_table,
unsigned int rule_id, unsigned int gw_id,
unsigned int priority, unsigned int weight)
{
- unsigned int i;
unsigned short gw_index;
- struct rule_info *r;
struct target *target;
+ struct rule_id_info *rid;
target = (struct target *)shm_malloc(sizeof(struct target));
if (target == NULL) {
@@ -135,17 +150,17 @@ int rule_hash_table_insert_target(struct rule_info **hash_table,
target->gw_index = gw_index;
target->priority = priority;
target->weight = weight;
-
- for (i = 0; i < lcr_rule_hash_size_param; i++) {
- r = hash_table[i];
- while (r) {
- if (r->rule_id == rule_id) {
- target->next = r->targets;
- r->targets = target;
- return 1;
- }
- r = r->next;
+
+ rid = rule_id_hash_table[rule_id % lcr_rule_hash_size_param];
+ while (rid) {
+ if (rid->rule_id == rule_id) {
+ target->next = rid->rule_addr->targets;
+ rid->rule_addr->targets = target;
+ LM_DBG("found rule with id <%u> and addr <%p>\n",
+ rule_id, rid->rule_addr);
+ return 1;
}
+ rid = rid->next;
}
LM_DBG("could not find (disabled) rule with id <%u>\n", rule_id);
@@ -201,3 +216,23 @@ void rule_hash_table_contents_free(struct rule_info **hash_table)
hash_table[i] = NULL;
}
}
+
+/* Free contents of rule_id hash table */
+void rule_id_hash_table_contents_free()
+{
+ int i;
+ struct rule_id_info *r, *next_r;
+
+ if (rule_id_hash_table == 0)
+ return;
+
+ for (i = 0; i <= lcr_rule_hash_size_param; i++) {
+ r = rule_id_hash_table[i];
+ while (r) {
+ next_r = r->next;
+ pkg_free(r);
+ r = next_r;
+ }
+ rule_id_hash_table[i] = NULL;
+ }
+}
diff --git a/modules/lcr/hash.h b/modules/lcr/hash.h
index bfe46e0..1ee6c3f 100644
--- a/modules/lcr/hash.h
+++ b/modules/lcr/hash.h
@@ -1,7 +1,7 @@
/*
* Header file for hash table functions
*
- * Copyright (C) 2008-2010 Juha Heinanen
+ * Copyright (C) 2008-2012 Juha Heinanen
*
* This file is part of SIP Router, a free SIP server.
*
@@ -51,4 +51,6 @@ struct rule_info *rule_hash_table_lookup(struct rule_info **hash_table,
void rule_hash_table_contents_free(struct rule_info **hash_table);
+void rule_id_hash_table_contents_free();
+
#endif
diff --git a/modules/lcr/lcr_mod.c b/modules/lcr/lcr_mod.c
index 0f68ed8..370e973 100644
--- a/modules/lcr/lcr_mod.c
+++ b/modules/lcr/lcr_mod.c
@@ -1,7 +1,7 @@
/*
* Least Cost Routing module
*
- * Copyright (C) 2005-2010 Juha Heinanen
+ * Copyright (C) 2005-2012 Juha Heinanen
* Copyright (C) 2006 Voice Sistem SRL
*
* This file is part of SIP Router, a free SIP server.
@@ -234,6 +234,9 @@ struct rule_info ***rule_pt = (struct rule_info ***)NULL;
/* Pointer to gw table pointer table */
struct gw_info **gw_pt = (struct gw_info **)NULL;
+/* Pointer to rule_id info hash table */
+struct rule_id_info **rule_id_hash_table = (struct rule_id_info **)NULL;
+
/*
* Functions that are defined later
*/
@@ -1185,13 +1188,23 @@ int reload_tables()
return -1;
}
+ rule_id_hash_table = pkg_malloc(sizeof(struct rule_id_info *) *
+ lcr_rule_hash_size_param);
+ if (!rule_id_hash_table) {
+ LM_ERR("no pkg memory for rule_id hash table\n");
+ goto err;
+ }
+ memset(rule_id_hash_table, 0, sizeof(struct rule_id_info *) *
+ lcr_rule_hash_size_param);
+
for (lcr_id = 1; lcr_id <= lcr_count_param; lcr_id++) {
/* Reload rules */
rules = rule_pt[0];
rule_hash_table_contents_free(rules);
-
+ rule_id_hash_table_contents_free();
+
if (lcr_dbf.use_table(dbh, &lcr_rule_table) < 0) {
LM_ERR("error while trying to use lcr_rule table\n");
goto err;
@@ -1507,11 +1520,15 @@ int reload_tables()
}
lcr_db_close();
+ rule_id_hash_table_contents_free();
+ if (rule_id_hash_table) pkg_free(rule_id_hash_table);
return 1;
err:
lcr_dbf.free_result(dbh, res);
lcr_db_close();
+ rule_id_hash_table_contents_free();
+ if (rule_id_hash_table) pkg_free(rule_id_hash_table);
return -1;
}
diff --git a/modules/lcr/lcr_mod.h b/modules/lcr/lcr_mod.h
index 87aafc4..1f82480 100644
--- a/modules/lcr/lcr_mod.h
+++ b/modules/lcr/lcr_mod.h
@@ -3,7 +3,7 @@
*
* Various lcr related constant, types, and external variables
*
- * Copyright (C) 2005-2010 Juha Heinanen
+ * Copyright (C) 2005-2012 Juha Heinanen
*
* This file is part of SIP Router, a free SIP server.
*
@@ -71,6 +71,12 @@ struct rule_info {
struct rule_info *next;
};
+struct rule_id_info {
+ unsigned int rule_id;
+ struct rule_info *rule_addr;
+ struct rule_id_info *next;
+};
+
struct target {
unsigned short gw_index;
unsigned short priority;
@@ -112,6 +118,7 @@ extern gen_lock_t *reload_lock;
extern struct gw_info **gw_pt;
extern struct rule_info ***rule_pt;
+extern struct rule_id_info **rule_id_hash_table;
extern int reload_tables();
extern int rpc_defunct_gw(unsigned int, unsigned int, unsigned int);