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 <amu...@redhat.com>
---
v3: Rebase on top of current main.
v2: Rebase on top of current main.
---
 controller/binding.c          |  4 +--
 controller/local_data.c       | 62 +++++++++++++++++------------------
 controller/local_data.h       | 15 +++++----
 controller/ovn-controller.c   | 19 ++++-------
 controller/physical.c         | 18 +++++-----
 controller/pinctrl.c          | 12 ++++---
 controller/route.c            |  8 ++---
 controller/test-lflow-cache.c | 27 +++++++--------
 8 files changed, 79 insertions(+), 86 deletions(-)

diff --git a/controller/binding.c b/controller/binding.c
index fdb0ad124..6d00802e6 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -738,10 +738,10 @@ update_ld_peers(const struct sbrec_port_binding *pb,
      * remove it from the ld peers list.
      */
     enum en_lport_type type = get_lport_type(pb);
-    int num_peers = ld->n_peer_ports;
+    size_t num_peers = vector_len(&ld->peer_ports);
     if (type != LP_PATCH) {
         remove_local_datapath_peer_port(pb, ld, local_datapaths);
-        if (num_peers != ld->n_peer_ports) {
+        if (num_peers != vector_len(&ld->peer_ports)) {
             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
             VLOG_DBG_RL(&rl,
                         "removing lport %s from the ld peers list",
diff --git a/controller/local_data.c b/controller/local_data.c
index e256de5fa..adda3b859 100644
--- a/controller/local_data.c
+++ b/controller/local_data.c
@@ -86,6 +86,7 @@ local_datapath_alloc(const struct sbrec_datapath_binding *dp)
     ld->datapath = dp;
     ld->is_switch = datapath_is_switch(dp);
     ld->is_transit_switch = datapath_is_transit_switch(dp);
+    ld->peer_ports = VECTOR_EMPTY_INITIALIZER(struct peer_ports);
     shash_init(&ld->external_ports);
     shash_init(&ld->multichassis_ports);
     /* memory accounting - common part. */
@@ -121,10 +122,9 @@ local_datapath_destroy(struct local_datapath *ld)
     local_datapath_usage -= (shash_count(&ld->multichassis_ports)
                              * sizeof *node);
     local_datapath_usage -= sizeof *ld;
-    local_datapath_usage -=
-        ld->n_allocated_peer_ports * sizeof *ld->peer_ports;
+    local_datapath_usage -= vector_memory_usage(&ld->peer_ports);
 
-    free(ld->peer_ports);
+    vector_destroy(&ld->peer_ports);
     shash_destroy(&ld->external_ports);
     shash_destroy(&ld->multichassis_ports);
     free(ld);
@@ -258,10 +258,11 @@ local_data_dump_peer_ports(struct hmap *local_datapaths, 
struct ds *peer_ports)
     HMAP_FOR_EACH (ld, hmap_node, local_datapaths) {
         const char *name = smap_get_def(&ld->datapath->external_ids, "name",
                                         "unknown");
-        for (size_t i = 0; i < ld->n_peer_ports; i++) {
+        struct peer_ports peers;
+        VECTOR_FOR_EACH (&ld->peer_ports, peers) {
             ds_put_format(peer_ports, "dp %s : local = %s, remote = %s\n",
-                          name, ld->peer_ports[i].local->logical_port,
-                          ld->peer_ports[i].remote->logical_port);
+                          name, peers.local->logical_port,
+                          peers.remote->logical_port);
         }
     }
 }
@@ -272,25 +273,26 @@ remove_local_datapath_peer_port(const struct 
sbrec_port_binding *pb,
                                 struct hmap *local_datapaths)
 {
     size_t i = 0;
-    for (i = 0; i < ld->n_peer_ports; i++) {
-        if (ld->peer_ports[i].local == pb) {
+    const struct peer_ports *peers;
+    VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
+        if (peers->local == pb) {
             break;
         }
+        i++;
     }
 
-    if (i == ld->n_peer_ports) {
+    struct peer_ports removed;
+    if (!vector_remove_fast(&ld->peer_ports, i, &removed)) {
         return;
     }
 
-    const struct sbrec_port_binding *peer = ld->peer_ports[i].remote;
-
-    /* Possible improvement: We can shrink the allocated peer ports
-     * if (ld->n_peer_ports < ld->n_allocated_peer_ports / 2).
-     */
-    ld->peer_ports[i].local = ld->peer_ports[ld->n_peer_ports - 1].local;
-    ld->peer_ports[i].remote = ld->peer_ports[ld->n_peer_ports - 1].remote;
-    ld->n_peer_ports--;
+    if (vector_len(&ld->peer_ports) < vector_capacity(&ld->peer_ports) / 2) {
+        local_datapath_usage -= vector_memory_usage(&ld->peer_ports);
+        vector_shrink_to_fit(&ld->peer_ports);
+        local_datapath_usage += vector_memory_usage(&ld->peer_ports);
+    }
 
+    const struct sbrec_port_binding *peer = removed.remote;
     struct local_datapath *peer_ld =
         get_local_datapath(local_datapaths, peer->datapath->tunnel_key);
     if (peer_ld) {
@@ -679,24 +681,20 @@ local_datapath_peer_port_add(struct local_datapath *ld,
                              const struct sbrec_port_binding *local,
                              const struct sbrec_port_binding *remote)
 {
-    for (size_t i = 0; i < ld->n_peer_ports; i++) {
-        if (ld->peer_ports[i].local == local) {
+    const struct peer_ports *ptr;
+    VECTOR_FOR_EACH_PTR (&ld->peer_ports, ptr) {
+        if (ptr->local == local) {
             return;
         }
     }
-    ld->n_peer_ports++;
-    if (ld->n_peer_ports > ld->n_allocated_peer_ports) {
-        size_t old_n_ports = ld->n_allocated_peer_ports;
-        ld->peer_ports =
-            x2nrealloc(ld->peer_ports,
-                       &ld->n_allocated_peer_ports,
-                       sizeof *ld->peer_ports);
-        local_datapath_usage +=
-            (ld->n_allocated_peer_ports - old_n_ports) *
-            sizeof *ld->peer_ports;
-    }
-    ld->peer_ports[ld->n_peer_ports - 1].local = local;
-    ld->peer_ports[ld->n_peer_ports - 1].remote = remote;
+
+   local_datapath_usage -= vector_memory_usage(&ld->peer_ports);
+    struct peer_ports peers = (struct peer_ports) {
+        .local = local,
+        .remote = remote,
+    };
+    vector_push(&ld->peer_ports, &peers);
+    local_datapath_usage += vector_memory_usage(&ld->peer_ports);
 }
 
 static bool
diff --git a/controller/local_data.h b/controller/local_data.h
index 19d558232..841829f2e 100644
--- a/controller/local_data.h
+++ b/controller/local_data.h
@@ -23,6 +23,7 @@
 
 /* OVN includes. */
 #include "lib/ovn-util.h"
+#include "vec.h"
 
 struct sbrec_datapath_binding;
 struct sbrec_port_binding;
@@ -32,6 +33,11 @@ struct ovsrec_bridge;
 struct ovsrec_interface_table;
 struct sbrec_load_balancer;
 
+struct peer_ports {
+    const struct sbrec_port_binding *local;
+    const struct sbrec_port_binding *remote;
+};
+
 /* A logical datapath that has some relevance to this hypervisor.  A logical
  * datapath D is relevant to hypervisor H if:
  *
@@ -53,13 +59,8 @@ struct local_datapath {
     /* The vtep port in this datapath, if any (at most one is allowed). */
     const struct sbrec_port_binding *vtep_port;
 
-    struct {
-        const struct sbrec_port_binding *local;
-        const struct sbrec_port_binding *remote;
-    } *peer_ports;
-
-    size_t n_peer_ports;
-    size_t n_allocated_peer_ports;
+    /* Vector of struct peer_ports. */
+    struct vector peer_ports;
 
     struct shash external_ports;
     struct shash multichassis_ports;
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 4266d9a9c..13cf1a503 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -2522,9 +2522,7 @@ en_mff_ovn_geneve_run(struct engine_node *node, void 
*data)
 struct load_balancers_by_dp {
     struct hmap_node node;
     const struct sbrec_datapath_binding *dp;
-    const struct sbrec_load_balancer **dp_lbs;
-    size_t n_allocated_dp_lbs;
-    size_t n_dp_lbs;
+    struct vector dp_lbs; /* Vector of const struct sbrec_load_balancer *. */
 };
 
 static struct load_balancers_by_dp *
@@ -2534,6 +2532,8 @@ load_balancers_by_dp_create(struct hmap *lbs,
     struct load_balancers_by_dp *lbs_by_dp = xzalloc(sizeof *lbs_by_dp);
 
     lbs_by_dp->dp = dp;
+    lbs_by_dp->dp_lbs =
+        VECTOR_EMPTY_INITIALIZER(const struct sbrec_load_balancer *);
     hmap_insert(lbs, &lbs_by_dp->node, hash_uint64(dp->tunnel_key));
     return lbs_by_dp;
 }
@@ -2545,7 +2545,7 @@ load_balancers_by_dp_destroy(struct load_balancers_by_dp 
*lbs_by_dp)
         return;
     }
 
-    free(lbs_by_dp->dp_lbs);
+    vector_destroy(&lbs_by_dp->dp_lbs);
     free(lbs_by_dp);
 }
 
@@ -2583,12 +2583,7 @@ load_balancers_by_dp_add_one(const struct hmap 
*local_datapaths,
         lbs_by_dp = load_balancers_by_dp_create(lbs, ldp->datapath);
     }
 
-    if (lbs_by_dp->n_dp_lbs == lbs_by_dp->n_allocated_dp_lbs) {
-        lbs_by_dp->dp_lbs = x2nrealloc(lbs_by_dp->dp_lbs,
-                                       &lbs_by_dp->n_allocated_dp_lbs,
-                                       sizeof *lbs_by_dp->dp_lbs);
-    }
-    lbs_by_dp->dp_lbs[lbs_by_dp->n_dp_lbs++] = lb;
+    vector_push(&lbs_by_dp->dp_lbs, &lb);
 }
 
 /* Builds and returns a hmap of 'load_balancers_by_dp', one record for each
@@ -3005,8 +3000,8 @@ lb_data_runtime_data_handler(struct engine_node *node, 
void *data OVS_UNUSED)
             continue;
         }
 
-        for (size_t i = 0; i < lbs_by_dp->n_dp_lbs; i++) {
-            const struct sbrec_load_balancer *sbrec_lb = lbs_by_dp->dp_lbs[i];
+        const struct sbrec_load_balancer *sbrec_lb;
+        VECTOR_FOR_EACH (&lbs_by_dp->dp_lbs, sbrec_lb) {
             struct ovn_controller_lb *lb =
                 ovn_controller_lb_find(&lb_data->local_lbs,
                                        &sbrec_lb->header_.uuid);
diff --git a/controller/physical.c b/controller/physical.c
index b4f91b134..4bca8bd1e 100644
--- a/controller/physical.c
+++ b/controller/physical.c
@@ -347,9 +347,9 @@ put_remote_port_redirect_bridged(const struct
         }
 
         uint32_t ls_dp_key = 0;
-        for (int i = 0; i < ld->n_peer_ports; i++) {
-            const struct sbrec_port_binding *sport_binding =
-                ld->peer_ports[i].remote;
+        const struct peer_ports *peers;
+        VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
+            const struct sbrec_port_binding *sport_binding = peers->remote;
             const char *sport_peer_name =
                 smap_get(&sport_binding->options, "peer");
             const char *distributed_port =
@@ -734,9 +734,9 @@ put_replace_chassis_mac_flows(const struct shash *ct_zones,
     int tag = localnet_port->tag ? *localnet_port->tag : 0;
     struct zone_ids zone_ids = get_zone_ids(localnet_port, ct_zones);
 
-    for (int i = 0; i < ld->n_peer_ports; i++) {
-        const struct sbrec_port_binding *rport_binding =
-            ld->peer_ports[i].remote;
+    const struct peer_ports *peers;
+    VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
+        const struct sbrec_port_binding *rport_binding = peers->remote;
         struct eth_addr router_port_mac;
         char *err_str = NULL;
         struct match match;
@@ -881,9 +881,9 @@ put_replace_router_port_mac_flows(const struct physical_ctx 
*ctx,
         return;
     }
 
-    for (int i = 0; i < ld->n_peer_ports; i++) {
-        const struct sbrec_port_binding *rport_binding =
-            ld->peer_ports[i].remote;
+    const struct peer_ports *peers;
+    VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
+        const struct sbrec_port_binding *rport_binding = peers->remote;
         struct eth_addr router_port_mac;
         struct match match;
         struct ofpact_mac *replace_mac;
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index bdb619b4d..f67a61758 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -1355,8 +1355,9 @@ fill_ipv6_prefix_state(struct ovsdb_idl_txn 
*ovnsb_idl_txn,
 {
     bool changed = false;
 
-    for (size_t i = 0; i < ld->n_peer_ports; i++) {
-        const struct sbrec_port_binding *pb = ld->peer_ports[i].local;
+    const struct peer_ports *peers;
+    VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
+        const struct sbrec_port_binding *pb = peers->local;
         struct ipv6_prefixd_state *pfd;
 
         if (!smap_get_bool(&pb->options, "ipv6_prefix", false)) {
@@ -4803,9 +4804,10 @@ send_garp_locally(struct ovsdb_idl_txn *ovnsb_idl_txn,
         get_local_datapath(local_datapaths, in_pb->datapath->tunnel_key);
 
     ovs_assert(ldp);
-    for (size_t i = 0; i < ldp->n_peer_ports; i++) {
-        const struct sbrec_port_binding *local = ldp->peer_ports[i].local;
-        const struct sbrec_port_binding *remote = ldp->peer_ports[i].remote;
+    const struct peer_ports *peers;
+    VECTOR_FOR_EACH_PTR (&ldp->peer_ports, peers) {
+        const struct sbrec_port_binding *local = peers->local;
+        const struct sbrec_port_binding *remote = peers->remote;
 
         /* Skip "ingress" port. */
         if (local == in_pb) {
diff --git a/controller/route.c b/controller/route.c
index 55d3e0ae3..4e5862529 100644
--- a/controller/route.c
+++ b/controller/route.c
@@ -158,7 +158,7 @@ route_run(struct route_ctx_in *r_ctx_in,
     build_port_mapping(&port_mapping, r_ctx_in->dynamic_routing_port_mapping);
 
     HMAP_FOR_EACH (ld, hmap_node, r_ctx_in->local_datapaths) {
-        if (!ld->n_peer_ports || ld->is_switch) {
+        if (vector_is_empty(&ld->peer_ports) || ld->is_switch) {
             continue;
         }
 
@@ -169,9 +169,9 @@ route_run(struct route_ctx_in *r_ctx_in,
 
         /* This is a LR datapath, find LRPs with route exchange options
          * that are bound locally. */
-        for (size_t i = 0; i < ld->n_peer_ports; i++) {
-            const struct sbrec_port_binding *local_peer
-                = ld->peer_ports[i].local;
+        const struct peer_ports *peers;
+        VECTOR_FOR_EACH_PTR (&ld->peer_ports, peers) {
+            const struct sbrec_port_binding *local_peer = peers->local;
             const struct sbrec_port_binding *repb =
                 route_exchange_find_port(r_ctx_in->sbrec_port_binding_by_name,
                                          r_ctx_in->chassis,
diff --git a/controller/test-lflow-cache.c b/controller/test-lflow-cache.c
index 7ce999360..6f29abce9 100644
--- a/controller/test-lflow-cache.c
+++ b/controller/test-lflow-cache.c
@@ -20,6 +20,7 @@
 #include "tests/ovstest.h"
 #include "tests/test-utils.h"
 #include "util.h"
+#include "vec.h"
 
 #include "lflow-cache.h"
 
@@ -111,9 +112,7 @@ test_lflow_cache_operations(struct ovs_cmdl_context *ctx)
     struct lflow_cache *lc = lflow_cache_create();
     struct expr *e = expr_create_boolean(true);
     bool enabled = !strcmp(ctx->argv[1], "true");
-    struct uuid *lflow_uuids = NULL;
-    size_t n_allocated_lflow_uuids = 0;
-    size_t n_lflow_uuids = 0;
+    struct vector lflow_uuids = VECTOR_EMPTY_INITIALIZER(struct uuid);
     unsigned int shift = 2;
     unsigned int n_ops;
 
@@ -152,16 +151,13 @@ test_lflow_cache_operations(struct ovs_cmdl_context *ctx)
                 goto done;
             }
 
-            if (n_lflow_uuids == n_allocated_lflow_uuids) {
-                lflow_uuids = x2nrealloc(lflow_uuids, &n_allocated_lflow_uuids,
-                                         sizeof *lflow_uuids);
-            }
-            struct uuid *lflow_uuid = &lflow_uuids[n_lflow_uuids++];
+            struct uuid lflow_uuid;
+            uuid_generate(&lflow_uuid);
+            vector_push(&lflow_uuids, &lflow_uuid);
 
-            uuid_generate(lflow_uuid);
-            test_lflow_cache_add__(lc, op_type, lflow_uuid, conj_id_ofs,
+            test_lflow_cache_add__(lc, op_type, &lflow_uuid, conj_id_ofs,
                                    n_conjs, e);
-            test_lflow_cache_lookup__(lc, lflow_uuid);
+            test_lflow_cache_lookup__(lc, &lflow_uuid);
         } else if (!strcmp(op, "add-del")) {
             const char *op_type = test_read_value(ctx, shift++, "op_type");
             if (!op_type) {
@@ -188,9 +184,10 @@ test_lflow_cache_operations(struct ovs_cmdl_context *ctx)
             test_lflow_cache_delete__(lc, &lflow_uuid);
             test_lflow_cache_lookup__(lc, &lflow_uuid);
         } else if (!strcmp(op, "del")) {
-            ovs_assert(n_lflow_uuids);
-            test_lflow_cache_delete__(lc, &lflow_uuids[n_lflow_uuids - 1]);
-            n_lflow_uuids--;
+            ovs_assert(!vector_is_empty(&lflow_uuids));
+            struct uuid lflow_uuid;
+            vector_pop(&lflow_uuids, &lflow_uuid);
+            test_lflow_cache_delete__(lc, &lflow_uuid);
         } else if (!strcmp(op, "enable")) {
             unsigned int limit;
             unsigned int mem_limit_kb;
@@ -236,7 +233,7 @@ test_lflow_cache_operations(struct ovs_cmdl_context *ctx)
     }
 done:
     lflow_cache_destroy(lc);
-    free(lflow_uuids);
+    vector_destroy(&lflow_uuids);
     expr_destroy(e);
 }
 
-- 
2.49.0

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to