[sr-dev] git:master: core/pv: use pv cache for pv_elem_t

Elena-Ramona Modroiu ramona at rosdev.ro
Wed Sep 26 12:19:46 CEST 2012


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

Author: Elena-Ramona Modroiu <ramona at asipto.com>
Committer: Elena-Ramona Modroiu <ramona at asipto.com>
Date:   Wed Sep 26 12:07:19 2012 +0200

core/pv: use pv cache for pv_elem_t

- reduces use of private memory for repetitive PVs

---

 pvapi.c |   44 +++++++++++++++++++++++++++++++++++++++++---
 pvar.h  |    3 ++-
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/pvapi.c b/pvapi.c
index 957086f..209d835 100644
--- a/pvapi.c
+++ b/pvapi.c
@@ -356,6 +356,40 @@ pv_spec_t* pv_cache_get(str *name)
 /**
  *
  */
+pv_spec_t* pv_spec_lookup(str *name, int *len)
+{
+	pv_spec_t *pvs;
+	str tname;
+
+	if(len!=NULL)
+		*len = 0;
+	if(name->s==NULL || name->len==0)
+	{
+		LM_ERR("invalid parameters\n");
+		return NULL;
+	}
+
+	tname.s = name->s;
+	tname.len = pv_locate_name(name);
+
+	if(tname.len < 0)
+		return NULL;
+
+	if(len!=NULL)
+		*len = tname.len;
+
+	pvs = pv_cache_lookup(&tname);
+
+	if(pvs!=NULL)
+		return pvs;
+
+	LM_DBG("PV <%.*s> is not in cache\n", tname.len, tname.s);
+	return pv_cache_add(&tname);
+}
+
+/**
+ *
+ */
 int register_pvars_mod(char *mod_name, pv_export_t *items)
 {
 	int ret;
@@ -943,6 +977,7 @@ int pv_parse_format(str *in, pv_elem_p *el)
 	int n = 0;
 	pv_elem_p e, e0;
 	str s;
+	int len;
 
 	if(in==NULL || in->s==NULL || el==NULL)
 		return -1;
@@ -985,7 +1020,10 @@ int pv_parse_format(str *in, pv_elem_p *el)
 			break;
 		s.s = p;
 		s.len = in->s+in->len-p;
-		p0 = pv_parse_spec(&s, &e->spec);
+		e->spec = pv_spec_lookup(&s, &len);
+		if(e->spec==NULL)
+			goto error;
+		p0 = p + len;
 		
 		if(p0==NULL)
 			goto error;
@@ -1250,8 +1288,8 @@ int pv_printf(struct sip_msg* msg, pv_elem_p list, char *buf, int *len)
 			}
 		}
 		/* put the value of the specifier */
-		if(it->spec.type!=PVT_NONE
-				&& pv_get_spec_value(msg, &(it->spec), &tok)==0)
+		if(it->spec!=NULL && it->spec->type!=PVT_NONE
+				&& pv_get_spec_value(msg, it->spec, &tok)==0)
 		{
 			if(tok.flags&PV_VAL_NULL)
 				tok.rs = pv_str_null;
diff --git a/pvar.h b/pvar.h
index eaa7556..f6d6318 100644
--- a/pvar.h
+++ b/pvar.h
@@ -164,7 +164,7 @@ typedef struct _pv_export {
 typedef struct _pv_elem
 {
 	str text;
-	pv_spec_t spec;
+	pv_spec_t *spec;
 	struct _pv_elem *next;
 } pv_elem_t, *pv_elem_p;
 
@@ -188,6 +188,7 @@ int pv_parse_format(str *in, pv_elem_p *el);
 int pv_parse_index(pv_spec_p sp, str *in);
 int pv_init_iname(pv_spec_p sp, int param);
 int pv_printf_s(struct sip_msg* msg, pv_elem_p list, str *s);
+pv_spec_t* pv_spec_lookup(str *name, int *len);
 
 typedef struct _pvname_list {
 	pv_spec_t sname;




More information about the sr-dev mailing list