Browse code

core eval expr: cache undefined results too

- internally cache undefined results of avp and pvar evaluations
(using RV_NONE for the val_type), between calls.
- fix wrong cache check for defined(pvar) (not used yet)

Andrei Pelinescu-Onciul authored on 28/04/2009 13:08:35
Showing 1 changed files
... ...
@@ -114,7 +114,7 @@ void rve_destroy(struct rval_expr* rve)
114 114
 
115 115
 void rval_cache_clean(struct rval_cache* rvc)
116 116
 {
117
-	if (rvc->cache_type==RV_CACHE_PVAR){
117
+	if ((rvc->cache_type==RV_CACHE_PVAR) && (rvc->val_type!=RV_NONE)){
118 118
 		pv_value_destroy(&rvc->c.pval);
119 119
 	}
120 120
 	rvc->cache_type=RV_CACHE_EMPTY;
... ...
@@ -264,7 +264,7 @@ struct rvalue* rval_new(enum rval_type t, union rval_val* v, int extra_size)
264 264
   * rval_cache_clean()'en when no longer needed.
265 265
   *
266 266
   * @param rv - target rvalue
267
-  * @param val_cache - value cache, might be filled if non-null, 
267
+  * @param val_cache - write-only: value cache, might be filled if non-null,
268 268
   *                    it _must_ be rval_cache_clean()'en when done.
269 269
   * @return - basic type or RV_NONE on error
270 270
   */
... ...
@@ -291,6 +291,7 @@ inline static enum rval_type rval_get_btype(struct run_act_ctx* h,
291 291
 		case RV_PVAR:
292 292
 			if (likely(val_cache && val_cache->cache_type==RV_CACHE_EMPTY)){
293 293
 				pv=&val_cache->c.pval;
294
+				val_cache->cache_type=RV_CACHE_PVAR;
294 295
 			}else{
295 296
 				val_cache=0;
296 297
 				pv=&tmp_pval;
... ...
@@ -298,24 +299,26 @@ inline static enum rval_type rval_get_btype(struct run_act_ctx* h,
298 298
 			memset(pv, 0, sizeof(tmp_pval));
299 299
 			if (likely(pv_get_spec_value(msg, &rv->v.pvs, pv)==0)){
300 300
 				if (pv->flags & PV_VAL_STR){
301
-					if (unlikely(val_cache==0)) pv_value_destroy(pv);
302
-					else{
303
-						val_cache->cache_type=RV_CACHE_PVAR;
301
+					if (likely(val_cache!=0))
304 302
 						val_cache->val_type=RV_STR;
305
-					}
303
+					else
304
+						pv_value_destroy(pv);
306 305
 					return RV_STR;
307 306
 				}else if (pv->flags & PV_TYPE_INT){
308
-					if (unlikely(val_cache==0)) pv_value_destroy(pv);
309
-					else{
310
-						val_cache->cache_type=RV_CACHE_PVAR;
307
+					if (likely(val_cache!=0))
311 308
 						val_cache->val_type=RV_INT;
312
-					}
309
+					else
310
+						pv_value_destroy(pv);
313 311
 					return RV_INT;
314 312
 				}else{
315 313
 					pv_value_destroy(pv);
314
+					if (likely(val_cache!=0))
315
+						val_cache->val_type=RV_NONE; /* undefined */
316 316
 					goto error;
317 317
 				}
318 318
 			}else{
319
+				if (likely(val_cache!=0))
320
+					val_cache->val_type=RV_NONE; /* undefined */
319 321
 				goto error;
320 322
 			}
321 323
 			break;
... ...
@@ -340,7 +343,6 @@ inline static enum rval_type rval_get_btype(struct run_act_ctx* h,
340 340
 				}
341 341
 			}else{
342 342
 				*ptype=RV_NONE;
343
-				if (val_cache) val_cache->cache_type=RV_CACHE_EMPTY;
344 343
 				goto error;
345 344
 			}
346 345
 			break;
... ...
@@ -753,7 +755,7 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
753 753
 			break;
754 754
 		case RV_PVAR:
755 755
 			if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
756
-				if (likely((cache->val_type==RV_INT) || 
756
+				if (likely((cache->val_type==RV_INT) ||
757 757
 								(cache->c.pval.flags & PV_VAL_INT))){
758 758
 					*i=cache->c.pval.ri;
759 759
 				}else if (cache->val_type==RV_STR){
... ...
@@ -1496,7 +1498,7 @@ inline static int rv_defined(struct run_act_ctx* h,
1496 1496
 		case RV_PVAR:
1497 1497
 			/* PV_VAL_NULL or pv_get_spec_value error => undef */
1498 1498
 			if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
1499
-				*res=(cache->val_type==RV_NONE);
1499
+				*res=(cache->val_type!=RV_NONE);
1500 1500
 			}else{
1501 1501
 				memset(&pval, 0, sizeof(pval));
1502 1502
 				if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){