On Mon, Sep 22, 2025 at 7:48 PM Mark Michelson <[email protected]> wrote:
> Hi Ales. This looks good to me. > > Acked-by: Mark Michelson <[email protected]> > > On Mon, Sep 22, 2025 at 6:13 AM Ales Musil via dev > <[email protected]> wrote: > > > > The vector has the same functionality as the x2nrealloc > > for insert. Use vector instead which slightly simplifies > > the final code. > > > > Signed-off-by: Ales Musil <[email protected]> > > --- > > controller/lflow.c | 40 ++++---- > > include/ovn/expr.h | 3 +- > > lib/actions.c | 30 +++--- > > lib/expr.c | 233 ++++++++++++++++++++++----------------------- > > 4 files changed, 156 insertions(+), 150 deletions(-) > > > > diff --git a/controller/lflow.c b/controller/lflow.c > > index 11ec33faf..197adaae9 100644 > > --- a/controller/lflow.c > > +++ b/controller/lflow.c > > @@ -447,21 +447,24 @@ consider_lflow_for_added_as_ips__( > > struct expr_constant_set *new_fake_as = NULL; > > struct in6_addr dummy_ip; > > bool has_dummy_ip = false; > > - ovs_assert(as_diff_added->n_values); > > + ovs_assert(vector_len(&as_diff_added->values)); > > > > /* When there is only 1 element, we append a dummy address and > create a > > * fake address set with 2 elements, so that the lflow parsing would > > * generate exactly the same format of flows as it would when > parsing with > > * the original address set. */ > > - if (as_diff_added->n_values == 1) { > > + if (vector_len(&as_diff_added->values) == 1) { > > new_fake_as = xzalloc(sizeof *new_fake_as); > > - new_fake_as->values = xzalloc(sizeof *new_fake_as->values * 2); > > - new_fake_as->n_values = 2; > > - new_fake_as->values[0] = new_fake_as->values[1] = > > - as_diff_added->values[0]; > > + new_fake_as->values = > > + VECTOR_CAPACITY_INITIALIZER(struct expr_constant, 2); > > + struct expr_constant c = > > + vector_get(&as_diff_added->values, 0, struct expr_constant); > > + vector_push(&new_fake_as->values, &c); > > /* Make a dummy ip that is different from the real one. */ > > - new_fake_as->values[1].value.u8_val++; > > - dummy_ip = new_fake_as->values[1].value.ipv6; > > + c.value.u8_val++; > > + dummy_ip = c.value.ipv6; > > + vector_push(&new_fake_as->values, &c); > > + > > has_dummy_ip = true; > > fake_as = new_fake_as; > > } > > @@ -528,13 +531,14 @@ consider_lflow_for_added_as_ips__( > > * the generated matches can't be mapped from the items in the > > * as_diff_added. So we need to fall back to reprocessing the lflow. > > */ > > - if (hmap_count(&matches) != as_ref_count * as_diff_added->n_values) > { > > + size_t n_values = vector_len(&as_diff_added->values); > > + if (hmap_count(&matches) != as_ref_count * n_values) { > > VLOG_DBG("lflow "UUID_FMT", addrset %s: Generated flows count " > > "(%"PRIuSIZE") " "doesn't match added addresses count " > > "(%"PRIuSIZE") and ref_count (%"PRIuSIZE"). " > > "Need reprocessing.", > > UUID_ARGS(&lflow->header_.uuid), as_name, > > - hmap_count(&matches), as_diff_added->n_values, > as_ref_count); > > + hmap_count(&matches), n_values, as_ref_count); > > handled = false; > > goto done; > > } > > @@ -610,19 +614,21 @@ as_update_can_be_handled(const char *as_name, > struct addr_set_diff *as_diff, > > struct expr_constant_set *as = shash_find_data(l_ctx_in->addr_sets, > > as_name); > > ovs_assert(as); > > - size_t n_added = as_diff->added ? as_diff->added->n_values : 0; > > - size_t n_deleted = as_diff->deleted ? as_diff->deleted->n_values : > 0; > > - size_t old_as_size = as->n_values + n_deleted - n_added; > > + size_t n_values = vector_len(&as->values); > > + size_t n_added = as_diff->added ? > vector_len(&as_diff->added->values) : 0; > > + size_t n_deleted = > > + as_diff->deleted ? vector_len(&as_diff->deleted->values) : 0; > > + size_t old_as_size = n_values + n_deleted - n_added; > > > > /* If the change may impact n_conj, i.e. the template of the flows > would > > * change, we must reprocess the lflow. */ > > - if (old_as_size <= 1 || as->n_values <= 1) { > > + if (old_as_size <= 1 || n_values <= 1) { > > return false; > > } > > > > /* If the size of the diff is too big, reprocessing may be more > > * efficient than incrementally processing the diffs. */ > > - if ((n_added + n_deleted) >= as->n_values) { > > + if ((n_added + n_deleted) >= n_values) { > > return false; > > } > > > > @@ -719,8 +725,8 @@ lflow_handle_addr_set_update(const char *as_name, > > > > if (as_diff->deleted) { > > struct addrset_info as_info; > > - for (size_t i = 0; i < as_diff->deleted->n_values; i++) { > > - struct expr_constant *c = &as_diff->deleted->values[i]; > > + const struct expr_constant *c; > > + VECTOR_FOR_EACH_PTR (&as_diff->deleted->values, c) { > > if (!as_info_from_expr_const(as_name, c, &as_info)) { > > continue; > > } > > diff --git a/include/ovn/expr.h b/include/ovn/expr.h > > index 9621a2c09..ae5ab1aab 100644 > > --- a/include/ovn/expr.h > > +++ b/include/ovn/expr.h > > @@ -537,8 +537,7 @@ void expr_constant_destroy(const struct > expr_constant *, > > > > /* A collection of "union expr_constant"s of the same type. */ > > struct expr_constant_set { > > - struct expr_constant *values; /* Constants. */ > > - size_t n_values; /* Number of constants. */ > > + struct vector values; /* Constants. */ > > enum expr_constant_type type; /* Type of the constants. */ > > bool in_curlies; /* Whether the constants were in {}. > */ > > }; > > diff --git a/lib/actions.c b/lib/actions.c > > index ba25fbc76..f0758752f 100644 > > --- a/lib/actions.c > > +++ b/lib/actions.c > > @@ -2109,7 +2109,7 @@ encode_event_empty_lb_backends_opts(struct ofpbuf > *ofpacts, > > /* All empty_lb_backends fields are of type 'str' */ > > ovs_assert(!strcmp(o->option->type, "str")); > > > > - const struct expr_constant *c = o->value.values; > > + const struct expr_constant *c = > vector_get_ptr(&o->value.values, 0); > > size_t size = strlen(c->string); > > struct controller_event_opt_header hdr = > > (struct controller_event_opt_header) { > > @@ -2585,11 +2585,11 @@ validate_empty_lb_backends(struct action_context > *ctx, > > { > > for (size_t i = 0; i < n_options; i++) { > > const struct ovnact_gen_option *o = &options[i]; > > - const struct expr_constant *c = o->value.values; > > + const struct expr_constant *c = > vector_get_ptr(&o->value.values, 0); > > struct sockaddr_storage ss; > > struct uuid uuid; > > > > - if (o->value.n_values > 1 || !c->string) { > > + if (vector_len(&o->value.values) > 1 || !c->string) { > > lexer_error(ctx->lexer, "Invalid value for \"%s\" option", > > o->option->name); > > return; > > @@ -2889,8 +2889,8 @@ encode_put_dhcpv4_option(const struct > ovnact_gen_option *o, > > uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2); > > opt_header[0] = o->option->code; > > > > - const struct expr_constant *c = o->value.values; > > - size_t n_values = o->value.n_values; > > + const struct expr_constant *c = vector_get_ptr(&o->value.values, 0); > > + size_t n_values = vector_len(&o->value.values); > > if (!strcmp(o->option->type, "bool") || > > !strcmp(o->option->type, "uint8")) { > > opt_header[1] = 1; > > @@ -3055,8 +3055,8 @@ encode_put_dhcpv6_option(const struct > ovnact_gen_option *o, > > struct ofpbuf *ofpacts) > > { > > struct dhcpv6_opt_header *opt = ofpbuf_put_uninit(ofpacts, sizeof > *opt); > > - const struct expr_constant *c = o->value.values; > > - size_t n_values = o->value.n_values; > > + const struct expr_constant *c = vector_get_ptr(&o->value.values, 0); > > + size_t n_values = vector_len(&o->value.values); > > size_t size; > > > > opt->code = htons(o->option->code); > > @@ -3103,7 +3103,9 @@ encode_PUT_DHCPV4_OPTS(const struct > ovnact_put_opts *pdo, > > * (skipping offerip the second time around). */ > > const struct ovnact_gen_option *offerip_opt = find_opt( > > pdo->options, pdo->n_options, 0); > > - ovs_be32 offerip = offerip_opt->value.values[0].value.ipv4; > > + const struct expr_constant *c = > > + vector_get_ptr(&offerip_opt->value.values, 0); > > + ovs_be32 offerip = c->value.ipv4; > > ofpbuf_put(ofpacts, &offerip, sizeof offerip); > > > > /* Encode bootfile_name opt (67) */ > > @@ -3111,7 +3113,7 @@ encode_PUT_DHCPV4_OPTS(const struct > ovnact_put_opts *pdo, > > find_opt(pdo->options, pdo->n_options, DHCP_OPT_BOOTFILE_CODE); > > if (boot_opt) { > > uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2); > > - const struct expr_constant *c = boot_opt->value.values; > > + c = vector_get_ptr(&boot_opt->value.values, 0); > > opt_header[0] = boot_opt->option->code; > > opt_header[1] = strlen(c->string); > > ofpbuf_put(ofpacts, c->string, opt_header[1]); > > @@ -3121,7 +3123,7 @@ encode_PUT_DHCPV4_OPTS(const struct > ovnact_put_opts *pdo, > > find_opt(pdo->options, pdo->n_options, > DHCP_OPT_BOOTFILE_ALT_CODE); > > if (boot_alt_opt) { > > uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2); > > - const struct expr_constant *c = boot_alt_opt->value.values; > > + c = vector_get_ptr(&boot_alt_opt->value.values, 0); > > opt_header[0] = boot_alt_opt->option->code; > > opt_header[1] = strlen(c->string); > > ofpbuf_put(ofpacts, c->string, opt_header[1]); > > @@ -3131,7 +3133,7 @@ encode_PUT_DHCPV4_OPTS(const struct > ovnact_put_opts *pdo, > > pdo->options, pdo->n_options, DHCP_OPT_NEXT_SERVER_CODE); > > if (next_server_opt) { > > uint8_t *opt_header = ofpbuf_put_zeros(ofpacts, 2); > > - const struct expr_constant *c = next_server_opt->value.values; > > + c = vector_get_ptr(&next_server_opt->value.values, 0); > > opt_header[0] = next_server_opt->option->code; > > opt_header[1] = sizeof(ovs_be32); > > ofpbuf_put(ofpacts, &c->value.ipv4, sizeof(ovs_be32)); > > @@ -3344,8 +3346,8 @@ parse_put_nd_ra_opts(struct action_context *ctx, > const struct expr_field *dst, > > /* Let's validate the options. */ > > for (size_t i = 0; i < po->n_options; i++) { > > const struct ovnact_gen_option *o = &po->options[i]; > > - const struct expr_constant *c = o->value.values; > > - if (o->value.n_values > 1) { > > + const struct expr_constant *c = > vector_get_ptr(&o->value.values, 0); > > + if (vector_len(&o->value.values) > 1) { > > lexer_error(ctx->lexer, "Invalid value for \"%s\" option", > > o->option->name); > > return; > > @@ -3527,7 +3529,7 @@ static void > > encode_put_nd_ra_option(const struct ovnact_gen_option *o, > > struct ofpbuf *ofpacts, ptrdiff_t ra_offset) > > { > > - const struct expr_constant *c = o->value.values; > > + const struct expr_constant *c = vector_get_ptr(&o->value.values, 0); > > > > switch (o->option->code) { > > case ND_RA_FLAG_ADDR_MODE: > > diff --git a/lib/expr.c b/lib/expr.c > > index 937fecb75..e01cd028f 100644 > > --- a/lib/expr.c > > +++ b/lib/expr.c > > @@ -585,8 +585,9 @@ type_check(struct expr_context *ctx, const struct > expr_field *f, > > } > > > > if (f->symbol->width) { > > - for (size_t i = 0; i < cs->n_values; i++) { > > - int w = expr_constant_width(&cs->values[i]); > > + const struct expr_constant *c; > > + VECTOR_FOR_EACH_PTR (&cs->values, c) { > > + int w = expr_constant_width(c); > > if (w > f->symbol->width) { > > lexer_error(ctx->lexer, > > "%d-bit constant is not compatible with > %d-bit " > > @@ -624,12 +625,13 @@ make_cmp(struct expr_context *ctx, > > f->symbol->name); > > goto exit; > > } > > - if (!cs->n_values) { > > + if (!vector_len(&cs->values)) { > > lexer_error(ctx->lexer, "Only == and != operators may be > used " > > "to compare a field against an empty value > set."); > > goto exit; > > } > > - if (cs->values[0].masked) { > > + const struct expr_constant *c = vector_get_ptr(&cs->values, 0); > > + if (c->masked) { > > lexer_error(ctx->lexer, "Only == and != operators may be > used " > > "with masked constants. Consider using > subfields " > > "instead (e.g. eth.src[0..15] > 0x1111 in place > of " > > @@ -641,9 +643,9 @@ make_cmp(struct expr_context *ctx, > > if (f->symbol->level == EXPR_L_NOMINAL) { > > if (f->symbol->predicate) { > > ovs_assert(f->symbol->width > 0); > > - for (size_t i = 0; i < cs->n_values; i++) { > > - const union mf_subvalue *value = &cs->values[i].value; > > - bool positive = (value->integer & htonll(1)) != 0; > > + const struct expr_constant *c; > > + VECTOR_FOR_EACH_PTR (&cs->values, c) { > > + bool positive = (c->value.integer & htonll(1)) != 0; > > positive ^= r == EXPR_R_NE; > > positive ^= ctx->not; > > if (!positive) { > > @@ -664,14 +666,15 @@ make_cmp(struct expr_context *ctx, > > } > > } > > > > - if (!cs->n_values) { > > + if (!vector_len(&cs->values)) { > > e = expr_create_boolean(r == EXPR_R_NE); > > goto exit; > > } > > - e = make_cmp__(f, r, &cs->values[0]); > > - for (size_t i = 1; i < cs->n_values; i++) { > > + e = make_cmp__(f, r, vector_get_ptr(&cs->values, 0)); > > + const struct expr_constant *values = vector_get_array(&cs->values); > > + for (size_t i = 1; i < vector_len(&cs->values); i++) { > > e = expr_combine(r == EXPR_R_EQ ? EXPR_T_OR : EXPR_T_AND, > > - e, make_cmp__(f, r, &cs->values[i])); > > + e, make_cmp__(f, r, &values[i])); > > } > > > > exit: > > @@ -767,7 +770,7 @@ assign_constant_set_type(struct expr_context *ctx, > > struct expr_constant_set *cs, > > enum expr_constant_type type) > > { > > - if (!cs->n_values || cs->type == type) { > > + if (!vector_len(&cs->values) || cs->type == type) { > > cs->type = type; > > return true; > > } else { > > @@ -778,8 +781,7 @@ assign_constant_set_type(struct expr_context *ctx, > > } > > > > static bool > > -parse_addr_sets(struct expr_context *ctx, struct expr_constant_set *cs, > > - size_t *allocated_values) > > +parse_addr_sets(struct expr_context *ctx, struct expr_constant_set *cs) > > { > > if (ctx->addr_sets_ref) { > > size_t *ref_count = shash_find_data(ctx->addr_sets_ref, > > @@ -806,23 +808,19 @@ parse_addr_sets(struct expr_context *ctx, struct > expr_constant_set *cs, > > } > > > > struct expr_constant_set *addr_sets = node->data; > > - size_t n_values = cs->n_values + addr_sets->n_values; > > - if (n_values >= *allocated_values) { > > - cs->values = xrealloc(cs->values, n_values * sizeof > *cs->values); > > - *allocated_values = n_values; > > - } > > - for (size_t i = 0; i < addr_sets->n_values; i++) { > > - struct expr_constant *c = &cs->values[cs->n_values++]; > > - *c = addr_sets->values[i]; > > - c->as_name = node->name; > > + vector_reserve(&cs->values, vector_len(&addr_sets->values)); > > + > > + struct expr_constant c; > > + VECTOR_FOR_EACH (&addr_sets->values, c) { > > + c.as_name = node->name; > > + vector_push(&cs->values, &c); > > } > > > > return true; > > } > > > > static bool > > -parse_port_group(struct expr_context *ctx, struct expr_constant_set *cs, > > - size_t *allocated_values) > > +parse_port_group(struct expr_context *ctx, struct expr_constant_set *cs) > > { > > struct ds sb_name = DS_EMPTY_INITIALIZER; > > > > @@ -847,29 +845,22 @@ parse_port_group(struct expr_context *ctx, struct > expr_constant_set *cs, > > return false; > > } > > > > - size_t n_values = cs->n_values + port_group->n_values; > > - if (n_values >= *allocated_values) { > > - cs->values = xrealloc(cs->values, n_values * sizeof > *cs->values); > > - *allocated_values = n_values; > > - } > > - for (size_t i = 0; i < port_group->n_values; i++) { > > - struct expr_constant *c = &cs->values[cs->n_values++]; > > - c->string = xstrdup(port_group->values[i].string); > > - c->as_name = NULL; > > + > > + vector_reserve(&cs->values, vector_len(&port_group->values)); > > + > > + struct expr_constant c; > > + VECTOR_FOR_EACH (&port_group->values, c) { > > + c.string = xstrdup(c.string); > > + c.as_name = NULL; > > + vector_push(&cs->values, &c); > > } > > > > return true; > > } > > > > static bool > > -parse_constant(struct expr_context *ctx, struct expr_constant_set *cs, > > - size_t *allocated_values) > > +parse_constant(struct expr_context *ctx, struct expr_constant_set *cs) > > { > > - if (cs->n_values >= *allocated_values) { > > - cs->values = x2nrealloc(cs->values, allocated_values, > > - sizeof *cs->values); > > - } > > - > > if (ctx->lexer->token.type == LEX_T_TEMPLATE) { > > lexer_error(ctx->lexer, "Unexpanded template."); > > return false; > > @@ -877,9 +868,11 @@ parse_constant(struct expr_context *ctx, struct > expr_constant_set *cs, > > if (!assign_constant_set_type(ctx, cs, EXPR_C_STRING)) { > > return false; > > } > > - struct expr_constant *c = &cs->values[cs->n_values++]; > > - c->string = xstrdup(ctx->lexer->token.s); > > - c->as_name = NULL; > > + > > + struct expr_constant c = (struct expr_constant) { > > + .string = xstrdup(ctx->lexer->token.s), > > + }; > > + vector_push(&cs->values, &c); > > lexer_get(ctx->lexer); > > return true; > > } else if (ctx->lexer->token.type == LEX_T_INTEGER || > > @@ -888,24 +881,26 @@ parse_constant(struct expr_context *ctx, struct > expr_constant_set *cs, > > return false; > > } > > > > - struct expr_constant *c = &cs->values[cs->n_values++]; > > - c->value = ctx->lexer->token.value; > > - c->format = ctx->lexer->token.format; > > - c->masked = ctx->lexer->token.type == LEX_T_MASKED_INTEGER; > > - if (c->masked) { > > - c->mask = ctx->lexer->token.mask; > > + bool masked = ctx->lexer->token.type == LEX_T_MASKED_INTEGER; > > + struct expr_constant c = (struct expr_constant) { > > + .value = ctx->lexer->token.value, > > + .format = ctx->lexer->token.format, > > + .masked = masked, > > + }; > > + if (masked) { > > + c.mask = ctx->lexer->token.mask; > > } > > - c->as_name = NULL; > > + vector_push(&cs->values, &c); > > lexer_get(ctx->lexer); > > return true; > > } else if (ctx->lexer->token.type == LEX_T_MACRO) { > > - if (!parse_addr_sets(ctx, cs, allocated_values)) { > > + if (!parse_addr_sets(ctx, cs)) { > > return false; > > } > > lexer_get(ctx->lexer); > > return true; > > } else if (ctx->lexer->token.type == LEX_T_PORT_GROUP) { > > - if (!parse_port_group(ctx, cs, allocated_values)) { > > + if (!parse_port_group(ctx, cs)) { > > return false; > > } > > lexer_get(ctx->lexer); > > @@ -923,22 +918,23 @@ parse_constant(struct expr_context *ctx, struct > expr_constant_set *cs, > > static bool > > parse_constant_set(struct expr_context *ctx, struct expr_constant_set > *cs) > > { > > - size_t allocated_values = 0; > > bool ok; > > > > - memset(cs, 0, sizeof *cs); > > + *cs = (struct expr_constant_set) { > > + .values = VECTOR_EMPTY_INITIALIZER(struct expr_constant), > > + }; > > if (lexer_match(ctx->lexer, LEX_T_LCURLY)) { > > ok = true; > > cs->in_curlies = true; > > do { > > - if (!parse_constant(ctx, cs, &allocated_values)) { > > + if (!parse_constant(ctx, cs)) { > > ok = false; > > break; > > } > > lexer_match(ctx->lexer, LEX_T_COMMA); > > } while (!lexer_match(ctx->lexer, LEX_T_RCURLY)); > > } else { > > - ok = parse_constant(ctx, cs, &allocated_values); > > + ok = parse_constant(ctx, cs); > > } > > if (!ok) { > > expr_constant_set_destroy(cs); > > @@ -964,13 +960,13 @@ expr_constant_parse(struct lexer *lexer, const > struct expr_field *f, > > .lexer = lexer, > > }; > > > > - struct expr_constant_set cs; > > - memset(&cs, 0, sizeof cs); > > - size_t allocated_values = 0; > > - if (parse_constant(&ctx, &cs, &allocated_values) > > + struct expr_constant_set cs = (struct expr_constant_set) { > > + .values = VECTOR_EMPTY_INITIALIZER(struct expr_constant), > > + }; > > + if (parse_constant(&ctx, &cs) > > && type_check(&ctx, f, &cs)) { > > - *c = cs.values[0]; > > - cs.n_values = 0; > > + *c = vector_get(&cs.values, 0, struct expr_constant); > > + vector_clear(&cs.values); > > } > > expr_constant_set_destroy(&cs); > > > > @@ -1031,19 +1027,18 @@ expr_constant_set_parse(struct lexer *lexer, > struct expr_constant_set *cs) > > void > > expr_constant_set_format(const struct expr_constant_set *cs, struct ds > *s) > > { > > - bool curlies = cs->in_curlies || cs->n_values != 1; > > + bool curlies = cs->in_curlies || vector_len(&cs->values) != 1; > > if (curlies) { > > ds_put_char(s, '{'); > > } > > > > - for (const struct expr_constant *c = cs->values; > > - c < &cs->values[cs->n_values]; c++) { > > - if (c != cs->values) { > > - ds_put_cstr(s, ", "); > > - } > > - > > + const struct expr_constant *c; > > + VECTOR_FOR_EACH_PTR (&cs->values, c) { > > expr_constant_format(c, cs->type, s); > > + ds_put_cstr(s, ", "); > > } > > + ds_chomp(s, ' '); > > + ds_chomp(s, ','); > > > > if (curlies) { > > ds_put_char(s, '}'); > > @@ -1055,11 +1050,12 @@ expr_constant_set_destroy(struct > expr_constant_set *cs) > > { > > if (cs) { > > if (cs->type == EXPR_C_STRING) { > > - for (size_t i = 0; i < cs->n_values; i++) { > > - free(cs->values[i].string); > > + const struct expr_constant *c; > > + VECTOR_FOR_EACH_PTR (&cs->values, c) { > > + free(c->string); > > } > > } > > - free(cs->values); > > + vector_destroy(&cs->values); > > } > > } > > > > @@ -1092,8 +1088,7 @@ expr_constant_set_create_integers(const char > *const *values, size_t n_values) > > { > > struct expr_constant_set *cs = xzalloc(sizeof *cs); > > cs->in_curlies = true; > > - cs->n_values = 0; > > - cs->values = xmalloc(n_values * sizeof *cs->values); > > + cs->values = VECTOR_CAPACITY_INITIALIZER(struct expr_constant, > n_values); > > cs->type = EXPR_C_INTEGER; > > for (size_t i = 0; i < n_values; i++) { > > /* Use the lexer to convert each constant set into the proper > > @@ -1106,40 +1101,41 @@ expr_constant_set_create_integers(const char > *const *values, size_t n_values) > > VLOG_WARN("Invalid constant set entry: '%s', token type: > %d", > > values[i], lex.token.type); > > } else { > > - struct expr_constant *c = &cs->values[cs->n_values++]; > > - c->value = lex.token.value; > > - c->format = lex.token.format; > > - c->masked = lex.token.type == LEX_T_MASKED_INTEGER; > > - if (c->masked) { > > - c->mask = lex.token.mask; > > + bool masked = lex.token.type == LEX_T_MASKED_INTEGER; > > + struct expr_constant c = (struct expr_constant) { > > + .value = lex.token.value, > > + .format = lex.token.format, > > + .masked = masked, > > + }; > > + if (masked) { > > + c.mask = lex.token.mask; > > } > > + vector_push(&cs->values, &c); > > } > > lexer_destroy(&lex); > > } > > > > /* Sort the result, so that it is efficient to generate diffs in the > > * function expr_constant_set_diff */ > > - qsort(cs->values, cs->n_values, sizeof *cs->values, > > - compare_expr_constant_integer_cb); > > + vector_qsort(&cs->values, compare_expr_constant_integer_cb); > > > > return cs; > > } > > > > static void > > expr_constant_set_add_value(struct expr_constant_set **p_cs, > > - struct expr_constant *c, size_t *allocated) > > + const struct expr_constant *c) > > { > > struct expr_constant_set *cs = *p_cs; > > if (!cs) { > > cs = xzalloc(sizeof *cs); > > + *cs = (struct expr_constant_set) { > > + .values = VECTOR_CAPACITY_INITIALIZER(struct expr_constant, 1), > > + }; > > *p_cs = cs; > > } > > > > - if (cs->n_values >= *allocated) { > > - cs->values = x2nrealloc(cs->values, allocated, > > - sizeof *cs->values); > > - } > > - cs->values[cs->n_values++] = *c; > > + vector_push(&cs->values, c); > > } > > > > /* Find the differences between old and new. Both old and new must be > integer > > @@ -1159,33 +1155,33 @@ expr_constant_set_integers_diff(struct > expr_constant_set *old, > > struct expr_constant_set *diff_added = NULL; > > struct expr_constant_set *diff_deleted = NULL; > > > > - size_t oi, ni, added_n_allocated, deleted_n_allocated; > > - added_n_allocated = deleted_n_allocated = 0; > > + size_t oi, ni; > > + > > + const struct expr_constant *old_c = vector_get_array(&old->values); > > + size_t old_n_values = vector_len(&old->values); > > > > - for (oi = ni = 0; oi < old->n_values && ni < new->n_values;) { > > - int d = compare_expr_constant_integer_cb(&old->values[oi], > > - &new->values[ni]); > > + const struct expr_constant *new_c = vector_get_array(&new->values); > > + size_t new_n_values = vector_len(&new->values); > > + > > + for (oi = ni = 0; oi < old_n_values && ni < new_n_values;) { > > + int d = compare_expr_constant_integer_cb(&old_c[oi], > &new_c[ni]); > > if (d < 0) { > > - expr_constant_set_add_value(&diff_deleted, &old->values[oi], > > - &deleted_n_allocated); > > + expr_constant_set_add_value(&diff_deleted, &old_c[oi]); > > oi++; > > } else if (d > 0) { > > - expr_constant_set_add_value(&diff_added, &new->values[ni], > > - &added_n_allocated); > > + expr_constant_set_add_value(&diff_added, &new_c[ni]); > > ni++; > > } else { > > oi++; ni++; > > } > > } > > > > - for (; oi < old->n_values; oi++) { > > - expr_constant_set_add_value(&diff_deleted, &old->values[oi], > > - &deleted_n_allocated); > > + for (; oi < old_n_values; oi++) { > > + expr_constant_set_add_value(&diff_deleted, &old_c[oi]); > > } > > > > - for (; ni < new->n_values; ni++) { > > - expr_constant_set_add_value(&diff_added, &new->values[ni], > > - &added_n_allocated); > > + for (; ni < new_n_values; ni++) { > > + expr_constant_set_add_value(&diff_added, &new_c[ni]); > > } > > > > *p_diff_added = diff_added; > > @@ -1228,8 +1224,7 @@ expr_const_sets_add_strings(struct shash > *const_sets, const char *name, > > { > > struct expr_constant_set *cs = xzalloc(sizeof *cs); > > cs->in_curlies = true; > > - cs->n_values = 0; > > - cs->values = xmalloc(n_values * sizeof *cs->values); > > + cs->values = VECTOR_CAPACITY_INITIALIZER(struct expr_constant, > n_values); > > cs->type = EXPR_C_STRING; > > for (size_t i = 0; i < n_values; i++) { > > if (filter && !sset_find(filter, values[i])) { > > @@ -1238,8 +1233,10 @@ expr_const_sets_add_strings(struct shash > *const_sets, const char *name, > > values[i], name); > > continue; > > } > > - struct expr_constant *c = &cs->values[cs->n_values++]; > > - c->string = xstrdup(values[i]); > > + struct expr_constant c = (struct expr_constant) { > > + .string = xstrdup(values[i]), > > + }; > > + vector_push(&cs->values, &c); > > } > > > > expr_const_sets_add(const_sets, name, cs); > > @@ -1351,14 +1348,15 @@ expr_parse_primary(struct expr_context *ctx, > bool *atomic) > > > > *atomic = true; > > > > - struct expr_constant *cst = xzalloc(sizeof *cst); > > - cst->format = LEX_F_HEXADECIMAL; > > - cst->masked = false; > > + struct expr_constant cst = (struct expr_constant) { > > + .format = LEX_F_HEXADECIMAL, > > + .masked = false, > > + }; > > > > + c.values = VECTOR_CAPACITY_INITIALIZER(struct > expr_constant, 1); > > c.type = EXPR_C_INTEGER; > > - c.values = cst; > > - c.n_values = 1; > > c.in_curlies = false; > > + vector_push(&c.values, &cst); > > return make_cmp(ctx, &f, EXPR_R_NE, &c); > > } else if (parse_relop(ctx, &r) && parse_constant_set(ctx, &c)) > { > > return make_cmp(ctx, &f, r, &c); > > @@ -1371,13 +1369,14 @@ expr_parse_primary(struct expr_context *ctx, > bool *atomic) > > return NULL; > > } > > > > + struct expr_constant *c = vector_get_ptr(&c1.values, 0); > > if (!expr_relop_from_token(ctx->lexer->token.type, NULL) > > - && c1.n_values == 1 > > + && vector_len(&c1.values) == 1 > > && c1.type == EXPR_C_INTEGER > > - && c1.values[0].format == LEX_F_DECIMAL > > - && !c1.values[0].masked > > + && c->format == LEX_F_DECIMAL > > + && !c->masked > > && !c1.in_curlies) { > > - uint64_t x = ntohll(c1.values[0].value.integer); > > + uint64_t x = ntohll(c->value.integer); > > if (x <= 1) { > > *atomic = true; > > expr_constant_set_destroy(&c1); > > -- > > 2.51.0 > > > > _______________________________________________ > > dev mailing list > > [email protected] > > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > > > Thank you Mark, I went ahead and merged this into main. Regards, Ales _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
