Module: sip-router Branch: master Commit: dcd67373212fe0a7e3694931b548fa5ccdf31500 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=dcd67373...
Author: Juha Heinanen jh@tutpro.com Committer: Juha Heinanen jh@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);