Jelajahi Sumber

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
Daniel-Constantin Mierla 14 tahun lalu
induk
melakukan
eef79d7f5e
3 mengubah file dengan 136 tambahan dan 121 penghapusan
  1. 133 118
      modules_k/htable/ht_api.c
  2. 2 2
      modules_k/htable/ht_api.h
  3. 1 1
      modules_k/htable/htable.c

+ 133 - 118
modules_k/htable/ht_api.c

@@ -24,7 +24,9 @@
 
 
 #include "../../mem/shm_mem.h"
 #include "../../mem/shm_mem.h"
 #include "../../mem/mem.h"
 #include "../../mem/mem.h"
+#include "../../shm_init.h"
 #include "../../dprint.h"
 #include "../../dprint.h"
+#include "../../parser/parse_param.h"
 #include "../../lib/kcore/hash_func.h"
 #include "../../lib/kcore/hash_func.h"
 #include "../../ut.h"
 #include "../../ut.h"
 #include "../../re.h"
 #include "../../re.h"
@@ -38,8 +40,104 @@
 
 
 
 
 ht_t *_ht_root = NULL;
 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)
 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;
 	return 0;
 }
 }
 
 
-
 int ht_cell_pkg_free(ht_cell_t *cell)
 int ht_cell_pkg_free(ht_cell_t *cell)
 {
 {
 	if(cell==NULL)
 	if(cell==NULL)
@@ -95,6 +192,7 @@ int ht_cell_pkg_free(ht_cell_t *cell)
 	return 0;
 	return 0;
 }
 }
 
 
+
 ht_t* ht_get_table(str *name)
 ht_t* ht_get_table(str *name)
 {
 {
 	unsigned int htid;
 	unsigned int htid;
@@ -117,7 +215,7 @@ ht_t* ht_get_table(str *name)
 	return NULL;
 	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;
 	unsigned int htid;
 	ht_t *ht;
 	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);
 	htid = ht_compute_hash(name);
 
 
 	/* does it exist */
 	/* does it exist */
-	ht = _ht_pkg_root;
+	ht = _ht_root;
 	while(ht!=NULL)
 	while(ht!=NULL)
 	{
 	{
 		if(htid == ht->htid && name->len==ht->name.len 
 		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->next;
 	}
 	}
 
 
-	ht = (ht_t*)pkg_malloc(sizeof(ht_t));
+	ht = (ht_t*)shm_malloc(sizeof(ht_t));
 	if(ht==NULL)
 	if(ht==NULL)
 	{
 	{
-		LM_ERR("no more pkg\n");
+		LM_ERR("no more shared memory\n");
 		return -1;
 		return -1;
 	}
 	}
 	memset(ht, 0, sizeof(ht_t));
 	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->dbtable = *dbtable;
 	ht->dbmode = dbmode;
 	ht->dbmode = dbmode;
 
 
-	ht->next = _ht_pkg_root;
-	_ht_pkg_root = ht;
+	ht->next = _ht_root;
+	_ht_root = ht;
 	return 0;
 	return 0;
 }
 }
 
 
-int ht_shm_init(void)
+int ht_init_tables(void)
 {
 {
-	ht_t *htp;
-	ht_t *htp0;
 	ht_t *ht;
 	ht_t *ht;
 	int i;
 	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));
 		ht->entries = (ht_entry_t*)shm_malloc(ht->htsize*sizeof(ht_entry_t));
 		if(ht->entries==NULL)
 		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);
 			shm_free(ht);
 			return -1;
 			return -1;
 		}
 		}
@@ -195,7 +282,8 @@ int ht_shm_init(void)
 		{
 		{
 			if(lock_init(&ht->entries[i].lock)==0)
 			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--;
 				i--;
 				while(i>=0)
 				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;
 	return 0;
 }
 }
@@ -512,129 +596,60 @@ int ht_dbg(void)
 
 
 int ht_table_spec(char *spec)
 int ht_table_spec(char *spec)
 {
 {
+	keyvalue_t kval;
 	str name;
 	str name;
 	str dbtable = {0, 0};
 	str dbtable = {0, 0};
 	unsigned int autoexpire = 0;
 	unsigned int autoexpire = 0;
 	unsigned int size = 4;
 	unsigned int size = 4;
-	int type = 0;
 	unsigned int dbmode = 0;
 	unsigned int dbmode = 0;
 	str in;
 	str in;
 	str tok;
 	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*/
 	/* parse: name=>dbtable=abc;autoexpire=123;size=123*/
 	in.s = spec;
 	in.s = spec;
 	in.len = strlen(in.s);
 	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;
 			dbtable = tok;
 			LM_DBG("htable [%.*s] - dbtable [%.*s]\n", name.len, name.s,
 			LM_DBG("htable [%.*s] - dbtable [%.*s]\n", name.len, name.s,
 					dbtable.len, dbtable.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)
 			if(str2int(&tok, &autoexpire)!=0)
 				goto error;
 				goto error;
 			LM_DBG("htable [%.*s] - expire [%u]\n", name.len, name.s,
 			LM_DBG("htable [%.*s] - expire [%u]\n", name.len, name.s,
 					autoexpire);
 					autoexpire);
-			break;
-		case 3:
+		} else if(pit->name.len==4 && strncmp(pit->name.s, "size", 4)==0) {
 			if(str2int(&tok, &size)!=0)
 			if(str2int(&tok, &size)!=0)
 				goto error;
 				goto error;
 			LM_DBG("htable [%.*s] - size [%u]\n", name.len, name.s,
 			LM_DBG("htable [%.*s] - size [%u]\n", name.len, name.s,
 					size);
 					size);
-			break;
-		case 4:
+		} else if(pit->name.len==6 && strncmp(pit->name.s, "dbmode", 6)==0) {
 			if(str2int(&tok, &dbmode)!=0)
 			if(str2int(&tok, &dbmode)!=0)
 				goto error;
 				goto error;
 			LM_DBG("htable [%.*s] - dbmode [%u]\n", name.len, name.s,
 			LM_DBG("htable [%.*s] - dbmode [%u]\n", name.len, name.s,
 					dbmode);
 					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:
 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;
 	return -1;
 }
 }
 
 

+ 2 - 2
modules_k/htable/ht_api.h

@@ -66,8 +66,8 @@ typedef struct _ht_pv {
 	pv_elem_t *pve;
 	pv_elem_t *pve;
 } ht_pv_t, *ht_pv_p;
 } 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_destroy(void);
 int ht_set_cell(ht_t *ht, str *name, int type, int_str *val, int mode);
 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);
 int ht_del_cell(ht_t *ht, str *name);

+ 1 - 1
modules_k/htable/htable.c

@@ -144,7 +144,7 @@ static int mod_init(void)
 		return -1;
 		return -1;
 	}
 	}
 
 
-	if(ht_shm_init()!=0)
+	if(ht_init_tables()!=0)
 		return -1;
 		return -1;
 	ht_db_init_params();
 	ht_db_init_params();