[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