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 > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
