[sr-dev] git:master: htable: added two new PVs

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


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

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Sat Apr 30 19:50:32 2011 +0200

htable: added two new PVs

- $shtinc(htable=>key) - add atomically 1 to the value of the item
- $shtdec(htable=>key) - decrement atomically 1 to the value of the item
- both return the new value of the item
- they work only with items having iteger values

---

 modules_k/htable/ht_api.c |  107 +++++++++++++++++++++++++++++++++++++++++++++
 modules_k/htable/ht_api.h |    2 +
 modules_k/htable/ht_var.c |   49 ++++++++++++++++++++
 modules_k/htable/ht_var.h |    5 ++-
 modules_k/htable/htable.c |    4 ++
 5 files changed, 166 insertions(+), 1 deletions(-)

diff --git a/modules_k/htable/ht_api.c b/modules_k/htable/ht_api.c
index 23bc59e..da473e6 100644
--- a/modules_k/htable/ht_api.c
+++ b/modules_k/htable/ht_api.c
@@ -516,6 +516,113 @@ int ht_del_cell(ht_t *ht, str *name)
 	return 0;
 }
 
+ht_cell_t* ht_cell_value_add(ht_t *ht, str *name, int val, int mode,
+		ht_cell_t *old)
+{
+	unsigned int idx;
+	unsigned int hid;
+	ht_cell_t *it, *prev, *cell;
+	time_t now;
+	int_str isval;
+
+	if(ht==NULL || ht->entries==NULL)
+		return NULL;
+
+	hid = ht_compute_hash(name);
+
+	idx = ht_get_entry(hid, ht->htsize);
+
+	now = 0;
+	if(ht->htexpire>0)
+		now = time(NULL);
+	prev = NULL;
+	if(mode) lock_get(&ht->entries[idx].lock);
+	it = ht->entries[idx].first;
+	while(it!=NULL && it->cellid < hid)
+	{
+		prev = it;
+		it = it->next;
+	}
+	while(it!=NULL && it->cellid == hid)
+	{
+		if(name->len==it->name.len
+				&& strncmp(name->s, it->name.s, name->len)==0)
+		{
+			/* update value */
+			if(it->flags&AVP_VAL_STR)
+			{
+				/* string value cannot be incremented */
+				if(mode) lock_release(&ht->entries[idx].lock);
+				return NULL;
+			} else {
+				it->value.n += val;
+				it->expire = now + ht->htexpire;
+				if(old!=NULL)
+				{
+					if(old->msize>=it->msize)
+					{
+						memcpy(old, it, it->msize);
+						lock_release(&ht->entries[idx].lock);
+						return old;
+					}
+				}
+				cell = (ht_cell_t*)pkg_malloc(it->msize);
+				if(cell!=NULL)
+					memcpy(cell, it, it->msize);
+
+				if(mode) lock_release(&ht->entries[idx].lock);
+				return cell;
+			}
+		}
+		prev = it;
+		it = it->next;
+	}
+	/* add val if htable has an integer init value */
+	if(ht->flags!=PV_VAL_INT)
+		return NULL;
+	isval.n = ht->initval.n + val;
+	it = ht_cell_new(name, 0, &isval, hid);
+	if(it == NULL)
+	{
+		LM_ERR("cannot create new cell.\n");
+		if(mode) lock_release(&ht->entries[idx].lock);
+		return NULL;
+	}
+	it->expire = now + ht->htexpire;
+	if(prev==NULL)
+	{
+		if(ht->entries[idx].first!=NULL)
+		{
+			it->next = ht->entries[idx].first;
+			ht->entries[idx].first->prev = it;
+		}
+		ht->entries[idx].first = it;
+	} else {
+		it->next = prev->next;
+		it->prev = prev;
+		if(prev->next)
+			prev->next->prev = it;
+		prev->next = it;
+	}
+	ht->entries[idx].esize++;
+	if(old!=NULL)
+	{
+		if(old->msize>=it->msize)
+		{
+			memcpy(old, it, it->msize);
+			lock_release(&ht->entries[idx].lock);
+			return old;
+		}
+	}
+	cell = (ht_cell_t*)pkg_malloc(it->msize);
+	if(cell!=NULL)
+		memcpy(cell, it, it->msize);
+
+	if(mode) lock_release(&ht->entries[idx].lock);
+	return cell;
+}
+
+
 ht_cell_t* ht_cell_pkg_copy(ht_t *ht, str *name, ht_cell_t *old)
 {
 	unsigned int idx;
diff --git a/modules_k/htable/ht_api.h b/modules_k/htable/ht_api.h
index 6a92f29..831267e 100644
--- a/modules_k/htable/ht_api.h
+++ b/modules_k/htable/ht_api.h
@@ -74,6 +74,8 @@ 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);
+ht_cell_t* ht_cell_value_add(ht_t *ht, str *name, int val, int mode,
+		ht_cell_t *old);
 
 int ht_dbg(void);
 ht_cell_t* ht_cell_pkg_copy(ht_t *ht, str *name, ht_cell_t *old);
diff --git a/modules_k/htable/ht_var.c b/modules_k/htable/ht_var.c
index 0d52254..627e70b 100644
--- a/modules_k/htable/ht_var.c
+++ b/modules_k/htable/ht_var.c
@@ -292,3 +292,52 @@ int pv_get_ht_cv(struct sip_msg *msg,  pv_param_t *param,
 	return pv_get_sintval(msg, param, res, cnt);
 }
 
+int pv_get_ht_add(struct sip_msg *msg,  pv_param_t *param,
+		pv_value_t *res, int val)
+{
+	str htname;
+	ht_cell_t *htc=NULL;
+	ht_pv_t *hpv;
+
+	hpv = (ht_pv_t*)param->pvn.u.dname;
+
+	if(hpv->ht==NULL)
+	{
+		hpv->ht = ht_get_table(&hpv->htname);
+		if(hpv->ht==NULL)
+			return pv_get_null(msg, param, res);
+	}
+	if(pv_printf_s(msg, hpv->pve, &htname)!=0)
+	{
+		LM_ERR("cannot get $ht name\n");
+		return -1;
+	}
+	htc = ht_cell_value_add(hpv->ht, &htname, val, 1, _htc_local);
+	if(htc==NULL)
+	{
+		return pv_get_null(msg, param, res);
+	}
+	if(_htc_local!=htc)
+	{
+		ht_cell_pkg_free(_htc_local);
+		_htc_local=htc;
+	}
+
+	if(htc->flags&AVP_VAL_STR)
+		return pv_get_null(msg, param, res);
+
+	/* integer */
+	return pv_get_sintval(msg, param, res, htc->value.n);
+}
+
+int pv_get_ht_inc(struct sip_msg *msg,  pv_param_t *param,
+		pv_value_t *res)
+{
+	return pv_get_ht_add(msg, param, res, 1);
+}
+
+int pv_get_ht_dec(struct sip_msg *msg,  pv_param_t *param,
+		pv_value_t *res)
+{
+	return pv_get_ht_add(msg, param, res, -1);
+}
diff --git a/modules_k/htable/ht_var.h b/modules_k/htable/ht_var.h
index e6856b2..4ee895f 100644
--- a/modules_k/htable/ht_var.h
+++ b/modules_k/htable/ht_var.h
@@ -38,6 +38,9 @@ int pv_get_ht_cn(struct sip_msg *msg,  pv_param_t *param,
 		pv_value_t *res);
 int pv_get_ht_cv(struct sip_msg *msg,  pv_param_t *param,
 		pv_value_t *res);
-
+int pv_get_ht_inc(struct sip_msg *msg,  pv_param_t *param,
+		pv_value_t *res);
+int pv_get_ht_dec(struct sip_msg *msg,  pv_param_t *param,
+		pv_value_t *res);
 
 #endif
diff --git a/modules_k/htable/htable.c b/modules_k/htable/htable.c
index 461817f..7d387cc 100644
--- a/modules_k/htable/htable.c
+++ b/modules_k/htable/htable.c
@@ -76,6 +76,10 @@ static pv_export_t mod_pvs[] = {
 		pv_parse_ht_name, 0, 0, 0 },
 	{ {"shtcv", sizeof("shtcv")-1}, PVT_OTHER, pv_get_ht_cv, 0,
 		pv_parse_ht_name, 0, 0, 0 },
+	{ {"shtinc", sizeof("shtinc")-1}, PVT_OTHER, pv_get_ht_inc, 0,
+		pv_parse_ht_name, 0, 0, 0 },
+	{ {"shtdec", sizeof("shtdec")-1}, PVT_OTHER, pv_get_ht_dec, 0,
+		pv_parse_ht_name, 0, 0, 0 },
 	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
 };
 




More information about the sr-dev mailing list