[master] 6efccf76a Avoid a second rbtree lookup in VRT_priv_task()

Nils Goroll nils.goroll at uplex.de
Mon Jan 11 16:45:07 UTC 2021


commit 6efccf76a0fa4dfd43a2ce2f740a3a839545422d
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Mon Jan 11 17:02:21 2021 +0100

    Avoid a second rbtree lookup in VRT_priv_task()
    
    For a red-black tree insert in vrt_priv_dynamic(), we performed a lookup
    and then an insert, resulting in basically the same tree traversal
    twice.
    
    We now prepare a new struct vrt_priv on the workspace and release it if
    the respective priv already existed on the tree.
    
    For a full workspace, we fall back to a lookup via
    vrt_priv_dynamic_get().

diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c
index 3beac7f3b..b006f52ae 100644
--- a/bin/varnishd/cache/cache_vrt_priv.c
+++ b/bin/varnishd/cache/cache_vrt_priv.c
@@ -134,26 +134,24 @@ vrt_priv_dynamic_get(struct vrt_privs *privs, uintptr_t vmod_id)
 static struct vmod_priv *
 vrt_priv_dynamic(struct ws *ws, struct vrt_privs *privs, uintptr_t vmod_id)
 {
-	struct vrt_priv *vp;
-	static struct vmod_priv *r;
+	struct vrt_priv *vp, *ovp;
 
 	AN(vmod_id);
 
-	/*
-	 * TODO: for insert == 1, we can avoid the VRBT_FIND:
-	 * call only VRT_INSERT and reset the ws if the element existed
-	 */
-	r = vrt_priv_dynamic_get(privs, vmod_id);
-	if (r)
-		return (r);
+	/* even if ws is full, return any existing priv */
+	if (WS_ReserveSize(ws, sizeof *vp) == 0)
+		return (vrt_priv_dynamic_get(privs, vmod_id));
 
-	vp = WS_Alloc(ws, sizeof *vp);
-	if (vp == NULL)
-		return (NULL);
+	vp = WS_Reservation(ws);
 	INIT_OBJ(vp, VRT_PRIV_MAGIC);
 	vp->vmod_id = vmod_id;
-	AZ(VRBT_INSERT(vrt_privs, privs, vp));
-	return (vp->priv);
+	ovp = VRBT_INSERT(vrt_privs, privs, vp);
+	if (ovp == NULL) {
+		WS_Release(ws, sizeof *vp);
+		return (vp->priv);
+	}
+	WS_Release(ws, 0);
+	return (ovp->priv);
 }
 
 static struct vrt_privs *


More information about the varnish-commit mailing list