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 299
 			memset(pv, 0, sizeof(tmp_pval));
299 300
 			if (likely(pv_get_spec_value(msg, &rv->v.pvs, pv)==0)){
300 301
 				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;
302
+					if (likely(val_cache!=0))
304 303
 						val_cache->val_type=RV_STR;
305
-					}
304
+					else
305
+						pv_value_destroy(pv);
306 306
 					return RV_STR;
307 307
 				}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;
308
+					if (likely(val_cache!=0))
311 309
 						val_cache->val_type=RV_INT;
312
-					}
310
+					else
311
+						pv_value_destroy(pv);
313 312
 					return RV_INT;
314 313
 				}else{
315 314
 					pv_value_destroy(pv);
315
+					if (likely(val_cache!=0))
316
+						val_cache->val_type=RV_NONE; /* undefined */
316 317
 					goto error;
317 318
 				}
318 319
 			}else{
320
+				if (likely(val_cache!=0))
321
+					val_cache->val_type=RV_NONE; /* undefined */
319 322
 				goto error;
320 323
 			}
321 324
 			break;
... ...
@@ -340,7 +343,6 @@ inline static enum rval_type rval_get_btype(struct run_act_ctx* h,
340 343
 				}
341 344
 			}else{
342 345
 				*ptype=RV_NONE;
343
-				if (val_cache) val_cache->cache_type=RV_CACHE_EMPTY;
344 346
 				goto error;
345 347
 			}
346 348
 			break;
... ...
@@ -753,7 +755,7 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
753 755
 			break;
754 756
 		case RV_PVAR:
755 757
 			if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
756
-				if (likely((cache->val_type==RV_INT) || 
758
+				if (likely((cache->val_type==RV_INT) ||
757 759
 								(cache->c.pval.flags & PV_VAL_INT))){
758 760
 					*i=cache->c.pval.ri;
759 761
 				}else if (cache->val_type==RV_STR){
... ...
@@ -1496,7 +1498,7 @@ inline static int rv_defined(struct run_act_ctx* h,
1496 1498
 		case RV_PVAR:
1497 1499
 			/* PV_VAL_NULL or pv_get_spec_value error => undef */
1498 1500
 			if (unlikely(cache && cache->cache_type==RV_CACHE_PVAR)){
1499
-				*res=(cache->val_type==RV_NONE);
1501
+				*res=(cache->val_type!=RV_NONE);
1500 1502
 			}else{
1501 1503
 				memset(&pval, 0, sizeof(pval));
1502 1504
 				if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){