void vdir_remove_backend(VRT_CTX, struct vdir *vd, VCL_BACKEND be, unsigned *cur) { unsigned u, n; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); if (be == NULL) { VRT_fail(ctx, "%s: NULL backend cannot be removed", VRT_BACKEND_string(vd->dir)); return; } CHECK_OBJ(be, DIRECTOR_MAGIC); vdir_wrlock(vd); for (u = 0; u < vd->n_backend; u++) if (vd->backend[u] == be) break; if (u == vd->n_backend) { vdir_unlock(vd); return; } n = (vd->n_backend - u) - 1; memmove(&vd->backend[u], &vd->backend[u+1], n * sizeof(vd->backend[0])); memmove(&vd->weight[u], &vd->weight[u+1], n * sizeof(vd->weight[0])); vd->n_backend--; if (cur) { assert(*cur <= vd->n_backend); if (u < *cur) (*cur)--; else if (*cur == vd->n_backend) *cur = 0; } vdir_unlock(vd); }
unsigned vdir_remove_backend(struct vdir *vd, VCL_BACKEND be) { unsigned u, n; CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); if (be == NULL) return (vd->n_backend); CHECK_OBJ(be, DIRECTOR_MAGIC); vdir_wrlock(vd); for (u = 0; u < vd->n_backend; u++) if (vd->backend[u] == be) break; if (u == vd->n_backend) { vdir_unlock(vd); return (vd->n_backend); } vd->total_weight -= vd->weight[u]; n = (vd->n_backend - u) - 1; memmove(&vd->backend[u], &vd->backend[u+1], n * sizeof(vd->backend[0])); memmove(&vd->weight[u], &vd->weight[u+1], n * sizeof(vd->weight[0])); vd->n_backend--; vdir_unlock(vd); return (vd->n_backend); }
unsigned vdir_add_backend(struct vdir *vd, VCL_BACKEND be, double weight) { unsigned u; CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); AN(be); vdir_wrlock(vd); if (vd->n_backend >= vd->l_backend) vdir_expand(vd, vd->l_backend + 16); assert(vd->n_backend < vd->l_backend); u = vd->n_backend++; vd->backend[u] = be; vd->weight[u] = weight; vd->total_weight += weight; vdir_unlock(vd); return (u); }
VCL_BACKEND vdir_pick_be(VRT_CTX, struct vdir *vd, double w) { unsigned u; VCL_BACKEND be = NULL; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); vdir_wrlock(vd); vdir_update_health(ctx, vd); if (vd->total_weight > 0.0) { u = vdir_pick_by_weight(vd, w * vd->total_weight); assert(u < vd->n_backend); be = vd->backend[u]; CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); } vdir_unlock(vd); return (be); }
void vdir_add_backend(VRT_CTX, struct vdir *vd, VCL_BACKEND be, double weight) { unsigned u; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(vd, VDIR_MAGIC); if (be == NULL) { VRT_fail(ctx, "%s: NULL backend cannot be added", VRT_BACKEND_string(vd->dir)); return; } AN(be); vdir_wrlock(vd); if (vd->n_backend >= vd->l_backend) vdir_expand(vd, vd->l_backend + 16); assert(vd->n_backend < vd->l_backend); u = vd->n_backend++; vd->backend[u] = be; vd->weight[u] = weight; vdir_unlock(vd); }
VCL_BACKEND vdir_pick_be(struct vdir *vd, double w, const struct busyobj *bo) { unsigned u; double tw = 0.0; VCL_BACKEND be = NULL; vdir_wrlock(vd); for (u = 0; u < vd->n_backend; u++) { if (vd->backend[u]->healthy(vd->backend[u], bo, NULL)) { vbit_clr(vd->vbm, u); tw += vd->weight[u]; } else vbit_set(vd->vbm, u); } if (tw > 0.0) { u = vdir_pick_by_weight(vd, w * tw, vd->vbm); assert(u < vd->n_backend); be = vd->backend[u]; CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC); } vdir_unlock(vd); return (be); }