[sr-dev] git:master: htable: init tables directly in shm

Daniel-Constantin Mierla miconda at gmail.com
Sun May 1 17:40:10 CEST 2011


Module: sip-router
Branch: master
Commit: eef79d7f5e0fcacbf4a01232cd5039e8a6a1b464
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=eef79d7f5e0fcacbf4a01232cd5039e8a6a1b464

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Sat Apr 30 12:10:14 2011 +0200

htable: init tables directly in shm

- initial developed version didn't have access to shared memory during
  parameter setting, starting with 3.0 shm is initialized before module
  parameter section, thus code was simplified getting rid of the
  temporary clone in pkg
- helper structure and functions to store and parse 'key=>value' strings
  added
- parsing of 'htable' parameter format was simplified reusing the
  parse_params() function

---

 modules_k/htable/ht_api.c |  251 ++++++++++++++++++++++++---------------------
 modules_k/htable/ht_api.h |    4 +-
 modules_k/htable/htable.c |    2 +-
 3 files changed, 136 insertions(+), 121 deletions(-)

diff --git a/modules_k/htable/ht_api.c b/modules_k/htable/ht_api.c
index fe9a66e..31f8543 100644
--- a/modules_k/htable/ht_api.c
+++ b/modules_k/htable/ht_api.c
@@ -24,7 +24,9 @@
 
 #include "../../mem/shm_mem.h"
 #include "../../mem/mem.h"
+#include "../../shm_init.h"
 #include "../../dprint.h"
+#include "../../parser/parse_param.h"
 #include "../../lib/kcore/hash_func.h"
 #include "../../ut.h"
 #include "../../re.h"
@@ -38,8 +40,104 @@
 
 
 ht_t *_ht_root = NULL;
-ht_t *_ht_pkg_root = NULL;
 
+typedef struct _keyvalue {
+	str key;
+	str value;
+	int type;
+	union {
+		param_t *params;
+	} u;
+} keyvalue_t;
+
+
+#define KEYVALUE_TYPE_NONE		0
+#define KEYVALUE_TYPE_PARAMS	1
+
+/**
+ * parse a string like: 'key=>value'
+ *   - the value can be parameter list: 'name1=value1;...;nameX=valueX'
+ */
+int keyvalue_parse_str(str *data, int type, keyvalue_t *res)
+{
+	char *p;
+	str s;
+	str in;
+	param_hooks_t phooks;
+
+	if(data==NULL || data->s==NULL || data->len<=0 || res==NULL)
+	{
+		LM_ERR("invalid parameters\n");
+		return -1;
+	}
+
+	memset(res, 0, sizeof(keyvalue_t));
+
+	in.s = data->s;
+	in.len = data->len;
+
+	p = in.s;
+	while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
+		p++;
+	if(p>in.s+in.len || *p=='\0')
+		goto error;
+	res->key.s = p;
+	while(p < in.s + in.len)
+	{
+		if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
+			break;
+		p++;
+	}
+	if(p>in.s+in.len || *p=='\0')
+		goto error;
+	res->key.len = (int)(p - res->key.s);
+	if(*p!='=')
+	{
+		while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
+			p++;
+		if(p>in.s+in.len || *p=='\0' || *p!='=')
+			goto error;
+	}
+	p++;
+	if(*p!='>')
+		goto error;
+	p++;
+	while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
+		p++;
+
+	s.s = p;
+	s.len = in.s + in.len - p;
+	res->value.s = s.s;
+	res->value.len = s.len;
+	res->type = type;
+	if(type==KEYVALUE_TYPE_PARAMS)
+	{
+		if(s.s[s.len-1]==';')
+			s.len--;
+		if (parse_params(&s, CLASS_ANY, &phooks, &res->u.params)<0)
+		{
+			LM_ERR("failed parsing params value\n");
+			goto error;
+		}
+	}
+	return 0;
+error:
+	LM_ERR("invalid input parameter [%.*s] at [%d]\n", in.len, in.s,
+			(int)(p-in.s));
+	return -1;
+}
+
+void keyvalue_destroy(keyvalue_t *res)
+{
+	if(res==NULL)
+		return;
+	if(res->type==KEYVALUE_TYPE_PARAMS)
+	{
+		if(res->u.params!=NULL)
+			free_params(res->u.params);
+	}
+	memset(res, 0, sizeof(keyvalue_t));
+}
 
 ht_cell_t* ht_cell_new(str *name, int type, int_str *val, unsigned int cellid)
 {
@@ -86,7 +184,6 @@ int ht_cell_free(ht_cell_t *cell)
 	return 0;
 }
 
-
 int ht_cell_pkg_free(ht_cell_t *cell)
 {
 	if(cell==NULL)
@@ -95,6 +192,7 @@ int ht_cell_pkg_free(ht_cell_t *cell)
 	return 0;
 }
 
+
 ht_t* ht_get_table(str *name)
 {
 	unsigned int htid;
@@ -117,7 +215,7 @@ ht_t* ht_get_table(str *name)
 	return NULL;
 }
 
-int ht_pkg_init(str *name, int autoexp, str *dbtable, int size, int dbmode)
+int ht_add_table(str *name, int autoexp, str *dbtable, int size, int dbmode)
 {
 	unsigned int htid;
 	ht_t *ht;
@@ -125,7 +223,7 @@ int ht_pkg_init(str *name, int autoexp, str *dbtable, int size, int dbmode)
 	htid = ht_compute_hash(name);
 
 	/* does it exist */
-	ht = _ht_pkg_root;
+	ht = _ht_root;
 	while(ht!=NULL)
 	{
 		if(htid == ht->htid && name->len==ht->name.len 
@@ -137,10 +235,10 @@ int ht_pkg_init(str *name, int autoexp, str *dbtable, int size, int dbmode)
 		ht = ht->next;
 	}
 
-	ht = (ht_t*)pkg_malloc(sizeof(ht_t));
+	ht = (ht_t*)shm_malloc(sizeof(ht_t));
 	if(ht==NULL)
 	{
-		LM_ERR("no more pkg\n");
+		LM_ERR("no more shared memory\n");
 		return -1;
 	}
 	memset(ht, 0, sizeof(ht_t));
@@ -157,35 +255,24 @@ int ht_pkg_init(str *name, int autoexp, str *dbtable, int size, int dbmode)
 		ht->dbtable = *dbtable;
 	ht->dbmode = dbmode;
 
-	ht->next = _ht_pkg_root;
-	_ht_pkg_root = ht;
+	ht->next = _ht_root;
+	_ht_root = ht;
 	return 0;
 }
 
-int ht_shm_init(void)
+int ht_init_tables(void)
 {
-	ht_t *htp;
-	ht_t *htp0;
 	ht_t *ht;
 	int i;
 
-	htp = _ht_pkg_root;
+	ht = _ht_root;
 
-	while(htp)
+	while(ht)
 	{
-		htp0 = htp->next;
-		ht = (ht_t*)shm_malloc(sizeof(ht_t));
-		if(ht==NULL)
-		{
-			LM_ERR("no more shm\n");
-			return -1;
-		}
-		memcpy(ht, htp, sizeof(ht_t));
-
 		ht->entries = (ht_entry_t*)shm_malloc(ht->htsize*sizeof(ht_entry_t));
 		if(ht->entries==NULL)
 		{
-			LM_ERR("no more shm.\n");
+			LM_ERR("no more shm for [%.*s]\n", ht->name.len, ht->name.s);
 			shm_free(ht);
 			return -1;
 		}
@@ -195,7 +282,8 @@ int ht_shm_init(void)
 		{
 			if(lock_init(&ht->entries[i].lock)==0)
 			{
-				LM_ERR("cannot initalize lock[%d]\n", i);
+				LM_ERR("cannot initalize lock[%d] in [%.*s]\n", i,
+						ht->name.len, ht->name.s);
 				i--;
 				while(i>=0)
 				{
@@ -208,12 +296,8 @@ int ht_shm_init(void)
 
 			}
 		}
-		ht->next = _ht_root;
-		_ht_root = ht;
-		pkg_free(htp);
-		htp = htp0;
+		ht = ht->next;
 	}
-	_ht_pkg_root = NULL;
 
 	return 0;
 }
@@ -512,129 +596,60 @@ int ht_dbg(void)
 
 int ht_table_spec(char *spec)
 {
+	keyvalue_t kval;
 	str name;
 	str dbtable = {0, 0};
 	unsigned int autoexpire = 0;
 	unsigned int size = 4;
-	int type = 0;
 	unsigned int dbmode = 0;
 	str in;
 	str tok;
-	char *p;
+	param_t *pit=NULL;
 
+	if(!shm_initialized())
+	{
+		LM_ERR("shared memory was not initialized\n");
+		return -1;
+	}
 	/* parse: name=>dbtable=abc;autoexpire=123;size=123*/
 	in.s = spec;
 	in.len = strlen(in.s);
-
-	p = in.s;
-	while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
-		p++;
-	if(p>in.s+in.len || *p=='\0')
-		goto error;
-	name.s = p;
-	while(p < in.s + in.len)
-	{
-		if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
-			break;
-		p++;
-	}
-	if(p>in.s+in.len || *p=='\0')
-		goto error;
-	name.len = p - name.s;
-	if(*p!='=')
-	{
-		while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
-			p++;
-		if(p>in.s+in.len || *p=='\0' || *p!='=')
-			goto error;
-	}
-	p++;
-	if(*p!='>')
-		goto error;
-	p++;
-	while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
-		p++;
-
-next_token:
-	tok.s = p;
-	while(p < in.s + in.len)
+	if(keyvalue_parse_str(&in, KEYVALUE_TYPE_PARAMS, &kval)<0)
 	{
-		if(*p=='=' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
-			break;
-		p++;
+		LM_ERR("failed parsing: %.*s\n", in.len, in.s);
+		return -1;
 	}
-	if(p>in.s+in.len || *p=='\0')
-		goto error;
-	tok.len = p - tok.s;
-	if(tok.len==7 && strncmp(tok.s, "dbtable", 7)==0)
-		type = 1;
-	else if(tok.len==10 && strncmp(tok.s, "autoexpire", 10)==0)
-		type = 2;
-	else if(tok.len==4 && strncmp(tok.s, "size", 4)==0)
-		type = 3;
-	else if(tok.len==6 && strncmp(tok.s, "dbmode", 6)==0)
-		type = 4;
-	else goto error;
+	name = kval.key;
 
-	if(*p!='=')
+	for (pit = kval.u.params; pit; pit=pit->next)
 	{
-		while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
-			p++;
-		if(p>in.s+in.len || *p=='\0' || *p!='=')
-			goto error;
-	}
-	p++;
-	while(p<in.s+in.len && (*p==' ' || *p=='\t' || *p=='\n' || *p=='\r'))
-		p++;
-	if(p>in.s+in.len || *p=='\0')
-		goto error;
-	tok.s = p;
-	while(p < in.s + in.len)
-	{
-		if(*p==';' || *p==' ' || *p=='\t' || *p=='\n' || *p=='\r')
-			break;
-		p++;
-	}
-	if(p>in.s+in.len || *p=='\0')
-		goto error;
-	tok.len = p - tok.s;
-	switch(type)
-	{
-		case 1:
+		tok = pit->body;
+		if(pit->name.len==7 && strncmp(pit->name.s, "dbtable", 7)==0) {
 			dbtable = tok;
 			LM_DBG("htable [%.*s] - dbtable [%.*s]\n", name.len, name.s,
 					dbtable.len, dbtable.s);
-			break;
-		case 2:
+		} else if(pit->name.len==10 && strncmp(pit->name.s, "autoexpire", 10)==0) {
 			if(str2int(&tok, &autoexpire)!=0)
 				goto error;
 			LM_DBG("htable [%.*s] - expire [%u]\n", name.len, name.s,
 					autoexpire);
-			break;
-		case 3:
+		} else if(pit->name.len==4 && strncmp(pit->name.s, "size", 4)==0) {
 			if(str2int(&tok, &size)!=0)
 				goto error;
 			LM_DBG("htable [%.*s] - size [%u]\n", name.len, name.s,
 					size);
-			break;
-		case 4:
+		} else if(pit->name.len==6 && strncmp(pit->name.s, "dbmode", 6)==0) {
 			if(str2int(&tok, &dbmode)!=0)
 				goto error;
 			LM_DBG("htable [%.*s] - dbmode [%u]\n", name.len, name.s,
 					dbmode);
-			break;
+		} else { goto error; }
 	}
-	while(p<in.s+in.len && (*p==';' || *p==' ' || *p=='\t'
-				|| *p=='\n' || *p=='\r'))
-		p++;
-	if(p<in.s+in.len)
-		goto next_token;
 
-	return ht_pkg_init(&name, autoexpire, &dbtable, size, dbmode);
+	return ht_add_table(&name, autoexpire, &dbtable, size, dbmode);
 
 error:
-	LM_ERR("invalid htable parameter [%.*s] at [%d]\n", in.len, in.s,
-			(int)(p-in.s));
+	LM_ERR("invalid htable parameter [%.*s]\n", in.len, in.s);
 	return -1;
 }
 
diff --git a/modules_k/htable/ht_api.h b/modules_k/htable/ht_api.h
index 71c8e21..a55e6cd 100644
--- a/modules_k/htable/ht_api.h
+++ b/modules_k/htable/ht_api.h
@@ -66,8 +66,8 @@ typedef struct _ht_pv {
 	pv_elem_t *pve;
 } ht_pv_t, *ht_pv_p;
 
-int ht_pkg_init(str *name, int autoexp, str *dbtable, int size, int dbmode);
-int ht_shm_init(void);
+int ht_add_table(str *name, int autoexp, str *dbtable, int size, int dbmode);
+int ht_init_tables(void);
 int ht_destroy(void);
 int ht_set_cell(ht_t *ht, str *name, int type, int_str *val, int mode);
 int ht_del_cell(ht_t *ht, str *name);
diff --git a/modules_k/htable/htable.c b/modules_k/htable/htable.c
index f7af1d9..461817f 100644
--- a/modules_k/htable/htable.c
+++ b/modules_k/htable/htable.c
@@ -144,7 +144,7 @@ static int mod_init(void)
 		return -1;
 	}
 
-	if(ht_shm_init()!=0)
+	if(ht_init_tables()!=0)
 		return -1;
 	ht_db_init_params();
 




More information about the sr-dev mailing list