Looks good.
On Mon, Mar 21, 2011 at 10:59 AM, Ben Pfaff <[email protected]> wrote: > In my opinion, this makes the code more obviously correct in many places, > because there are generally fewer variables. One must generally keep two > variables in sync for iterating through an array: the array index and the > contents of the array at that index. For iterating through an hmap, only > the map element is necessary. > > A linked list would also be a reasonable choice for the bridge's collection > of ports. I chose to use an hmap because we already had an index by name > and it seemed OK to use only one index. I decided not to keep the shash > because they are less convenient for iteration than an hmap. > --- > vswitchd/bridge.c | 167 > +++++++++++++++++++++++------------------------------ > 1 files changed, 73 insertions(+), 94 deletions(-) > > diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c > index 52b4c95..2d0df9b 100644 > --- a/vswitchd/bridge.c > +++ b/vswitchd/bridge.c > @@ -155,12 +155,13 @@ struct mirror { > #define FLOOD_PORT ((struct port *) 1) /* The 'flood' output port. */ > struct port { > struct bridge *bridge; > - size_t port_idx; > + struct hmap_node hmap_node; /* Element in struct bridge's "ports" hmap. > */ > + char *name; > + > int vlan; /* -1=trunk port, else a 12-bit VLAN ID. */ > unsigned long *trunks; /* Bitmap of trunked VLANs, if 'vlan' == -1. > * NULL if all VLANs are trunked. */ > const struct ovsrec_port *cfg; > - char *name; > > /* Monitoring. */ > struct netdev_monitor *monitor; /* Tracks carrier. NULL if miimon. */ > @@ -213,10 +214,8 @@ struct bridge { > struct hmap ifaces; /* Contains "struct iface"s. */ > > /* Bridge ports. */ > - struct port **ports; > - size_t n_ports, allocated_ports; > + struct hmap ports; /* "struct port"s indexed by name. */ > struct shash iface_by_name; /* "struct iface"s indexed by name. */ > - struct shash port_by_name; /* "struct port"s indexed by name. */ > > /* Bonding. */ > bool has_bonded_ports; > @@ -464,22 +463,19 @@ iterate_and_prune_ifaces(struct bridge *br, > void *aux), > void *aux) > { > - size_t i; > + struct port *port, *next_port; > > - for (i = 0; i < br->n_ports; ) { > - struct port *port = br->ports[i]; > - struct iface *iface, *next; > + HMAP_FOR_EACH_SAFE (port, next_port, hmap_node, &br->ports) { > + struct iface *iface, *next_iface; > > - LIST_FOR_EACH_SAFE (iface, next, port_elem, &port->ifaces) { > + LIST_FOR_EACH_SAFE (iface, next_iface, port_elem, &port->ifaces) { > if (!cb(br, iface, aux)) { > iface_set_ofport(iface->cfg, -1); > iface_destroy(iface); > } > } > > - if (port->n_ifaces) { > - i++; > - } else { > + if (!port->n_ifaces) { > VLOG_WARN("%s port has no interfaces, dropping", port->name); > port_destroy(port); > } > @@ -810,7 +806,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch > *ovs_cfg) > "with another vswitch, choose an engine id less > " > "than 128", br->name); > } > - if (br->n_ports > 508) { > + if (hmap_count(&br->ports) > 508) { > VLOG_WARN("bridge %s: netflow port mangling will conflict > " > "with another port when more than 508 ports are > " > "used", br->name); > @@ -884,8 +880,9 @@ bridge_reconfigure(const struct ovsrec_open_vswitch > *ovs_cfg) > bridge_reconfigure_remotes(br, managers, n_managers); > } > LIST_FOR_EACH (br, node, &all_bridges) { > - for (i = 0; i < br->n_ports; i++) { > - struct port *port = br->ports[i]; > + struct port *port; > + > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > struct iface *iface; > > if (port->monitor) { > @@ -949,7 +946,7 @@ bridge_pick_local_hw_addr(struct bridge *br, uint8_t > ea[ETH_ADDR_LEN], > struct iface **hw_addr_iface) > { > const char *hwaddr; > - size_t i; > + struct port *port; > int error; > > *hw_addr_iface = NULL; > @@ -970,8 +967,7 @@ bridge_pick_local_hw_addr(struct bridge *br, uint8_t > ea[ETH_ADDR_LEN], > /* Otherwise choose the minimum non-local MAC address among all of the > * interfaces. */ > memset(ea, 0xff, ETH_ADDR_LEN); > - for (i = 0; i < br->n_ports; i++) { > - struct port *port = br->ports[i]; > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > uint8_t iface_ea[ETH_ADDR_LEN]; > struct iface *candidate; > struct iface *iface; > @@ -1444,10 +1440,9 @@ bridge_run(void) > > txn = ovsdb_idl_txn_create(idl); > LIST_FOR_EACH (br, node, &all_bridges) { > - size_t i; > + struct port *port; > > - for (i = 0; i < br->n_ports; i++) { > - struct port *port = br->ports[i]; > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > struct iface *iface; > > LIST_FOR_EACH (iface, port_elem, &port->ifaces) { > @@ -1473,7 +1468,7 @@ bridge_wait(void) > struct bridge *br; > > LIST_FOR_EACH (br, node, &all_bridges) { > - size_t i; > + struct port *port; > > ofproto_wait(br->ofproto); > if (ofproto_has_primary_controller(br->ofproto)) { > @@ -1482,8 +1477,8 @@ bridge_wait(void) > > mac_learning_wait(br->ml); > > - for (i = 0; i < br->n_ports; i++) { > - port_wait(br->ports[i]); > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > + port_wait(port); > } > } > ovsdb_idl_wait(idl); > @@ -1652,9 +1647,8 @@ bridge_create(const struct ovsrec_bridge *br_cfg) > br->ml = mac_learning_create(); > eth_addr_nicira_random(br->default_ea); > > + hmap_init(&br->ports); > hmap_init(&br->ifaces); > - > - shash_init(&br->port_by_name); > shash_init(&br->iface_by_name); > > br->flush = false; > @@ -1670,10 +1664,11 @@ static void > bridge_destroy(struct bridge *br) > { > if (br) { > + struct port *port, *next; > int error; > > - while (br->n_ports > 0) { > - port_destroy(br->ports[br->n_ports - 1]); > + HMAP_FOR_EACH_SAFE (port, next, hmap_node, &br->ports) { > + port_destroy(port); > } > list_remove(&br->node); > error = dpif_delete(br->dpif); > @@ -1685,9 +1680,8 @@ bridge_destroy(struct bridge *br) > ofproto_destroy(br->ofproto); > mac_learning_destroy(br->ml); > hmap_destroy(&br->ifaces); > - shash_destroy(&br->port_by_name); > + hmap_destroy(&br->ports); > shash_destroy(&br->iface_by_name); > - free(br->ports); > free(br->name); > free(br); > } > @@ -1754,7 +1748,7 @@ bridge_unixctl_reconnect(struct unixctl_conn *conn, > static int > bridge_run_one(struct bridge *br) > { > - size_t i; > + struct port *port; > int error; > > error = ofproto_run1(br->ofproto); > @@ -1764,8 +1758,8 @@ bridge_run_one(struct bridge *br) > > mac_learning_run(br->ml, ofproto_get_revalidate_set(br->ofproto)); > > - for (i = 0; i < br->n_ports; i++) { > - port_run(br->ports[i]); > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > + port_run(port); > } > > error = ofproto_run2(br->ofproto, br->flush); > @@ -1798,18 +1792,13 @@ bridge_get_controllers(const struct bridge *br, > static void > bridge_reconfigure_one(struct bridge *br) > { > - struct shash old_ports, new_ports; > + enum ofproto_fail_mode fail_mode; > struct svec snoops, old_snoops; > + struct port *port, *next; > struct shash_node *node; > - enum ofproto_fail_mode fail_mode; > + struct shash new_ports; > size_t i; > > - /* Collect old ports. */ > - shash_init(&old_ports); > - for (i = 0; i < br->n_ports; i++) { > - shash_add(&old_ports, br->ports[i]->name, br->ports[i]); > - } > - > /* Collect new ports. */ > shash_init(&new_ports); > for (i = 0; i < br->cfg->n_ports; i++) { > @@ -1839,11 +1828,10 @@ bridge_reconfigure_one(struct bridge *br) > > /* Get rid of deleted ports. > * Get rid of deleted interfaces on ports that still exist. */ > - SHASH_FOR_EACH (node, &old_ports) { > - struct port *port = node->data; > + HMAP_FOR_EACH_SAFE (port, next, hmap_node, &br->ports) { > const struct ovsrec_port *port_cfg; > > - port_cfg = shash_find_data(&new_ports, node->name); > + port_cfg = shash_find_data(&new_ports, port->name); > if (!port_cfg) { > port_destroy(port); > } else { > @@ -1855,7 +1843,7 @@ bridge_reconfigure_one(struct bridge *br) > * Add new interfaces to existing ports. > * Reconfigure existing ports. */ > SHASH_FOR_EACH (node, &new_ports) { > - struct port *port = shash_find_data(&old_ports, node->name); > + struct port *port = port_lookup(br, node->name); > if (!port) { > port = port_create(br, node->name); > } > @@ -1867,7 +1855,6 @@ bridge_reconfigure_one(struct bridge *br) > port_destroy(port); > } > } > - shash_destroy(&old_ports); > shash_destroy(&new_ports); > > /* Set the fail-mode */ > @@ -2069,11 +2056,10 @@ bridge_reconfigure_remotes(struct bridge *br, > static void > bridge_get_all_ifaces(const struct bridge *br, struct shash *ifaces) > { > - size_t i; > + struct port *port; > > shash_init(ifaces); > - for (i = 0; i < br->n_ports; i++) { > - struct port *port = br->ports[i]; > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > struct iface *iface; > > LIST_FOR_EACH (iface, port_elem, &port->ifaces) { > @@ -2098,11 +2084,10 @@ bridge_fetch_dp_ifaces(struct bridge *br) > { > struct dpif_port_dump dump; > struct dpif_port dpif_port; > - size_t i; > + struct port *port; > > /* Reset all interface numbers. */ > - for (i = 0; i < br->n_ports; i++) { > - struct port *port = br->ports[i]; > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > struct iface *iface; > > LIST_FOR_EACH (iface, port_elem, &port->ifaces) { > @@ -2592,7 +2577,6 @@ compose_dsts(const struct bridge *br, const struct flow > *flow, uint16_t vlan, > mirror_mask_t mirrors = in_port->src_mirrors; > struct dst dst; > int flow_vlan; > - size_t i; > > flow_vlan = vlan_tci_to_vid(flow->vlan_tci); > if (flow_vlan == 0) { > @@ -2600,8 +2584,9 @@ compose_dsts(const struct bridge *br, const struct flow > *flow, uint16_t vlan, > } > > if (out_port == FLOOD_PORT) { > - for (i = 0; i < br->n_ports; i++) { > - struct port *port = br->ports[i]; > + struct port *port; > + > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > if (port != in_port > && port_is_floodable(port) > && port_includes_vlan(port, vlan) > @@ -2627,8 +2612,9 @@ compose_dsts(const struct bridge *br, const struct flow > *flow, uint16_t vlan, > dst_set_add(set, &dst); > } > } else { > - for (i = 0; i < br->n_ports; i++) { > - struct port *port = br->ports[i]; > + struct port *port; > + > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > if (port_includes_vlan(port, m->out_vlan) > && set_dst(&dst, flow, in_port, port, tags)) > { > @@ -3043,16 +3029,15 @@ static void > bridge_account_checkpoint_ofhook_cb(void *br_) > { > struct bridge *br = br_; > + struct port *port; > long long int now; > - size_t i; > > if (!br->has_bonded_ports) { > return; > } > > now = time_msec(); > - for (i = 0; i < br->n_ports; i++) { > - struct port *port = br->ports[i]; > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > if (port->n_ifaces > 1 && port->bond_mode != BM_AB > && now >= port->bond_next_rebalance) { > port->bond_next_rebalance = now + port->bond_rebalance_interval; > @@ -3466,10 +3451,9 @@ bond_unixctl_list(struct unixctl_conn *conn, > ds_put_cstr(&ds, "bridge\tbond\ttype\tslaves\n"); > > LIST_FOR_EACH (br, node, &all_bridges) { > - size_t i; > + struct port *port; > > - for (i = 0; i < br->n_ports; i++) { > - const struct port *port = br->ports[i]; > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > if (port->n_ifaces > 1) { > struct iface *iface; > > @@ -3495,10 +3479,9 @@ bond_find(const char *name) > const struct bridge *br; > > LIST_FOR_EACH (br, node, &all_bridges) { > - size_t i; > + struct port *port; > > - for (i = 0; i < br->n_ports; i++) { > - struct port *port = br->ports[i]; > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > if (!strcmp(port->name, name) && port->n_ifaces > 1) { > return port; > } > @@ -3901,19 +3884,13 @@ port_create(struct bridge *br, const char *name) > > port = xzalloc(sizeof *port); > port->bridge = br; > - port->port_idx = br->n_ports; > port->vlan = -1; > port->trunks = NULL; > port->name = xstrdup(name); > port->active_iface = NULL; > list_init(&port->ifaces); > > - if (br->n_ports >= br->allocated_ports) { > - br->ports = x2nrealloc(br->ports, &br->allocated_ports, > - sizeof *br->ports); > - } > - br->ports[br->n_ports++] = port; > - shash_add_assert(&br->port_by_name, port->name, port); > + hmap_insert(&br->ports, &port->hmap_node, hash_string(port->name, 0)); > > VLOG_INFO("created port %s on bridge %s", port->name, br->name); > bridge_flush(br); > @@ -4208,7 +4185,6 @@ port_destroy(struct port *port) > if (port) { > struct bridge *br = port->bridge; > struct iface *iface, *next; > - struct port *del; > int i; > > for (i = 0; i < MAX_MIRRORS; i++) { > @@ -4222,10 +4198,7 @@ port_destroy(struct port *port) > iface_destroy(iface); > } > > - shash_find_and_delete_assert(&br->port_by_name, port->name); > - > - del = br->ports[port->port_idx] = br->ports[--br->n_ports]; > - del->port_idx = port->port_idx; > + hmap_remove(&br->ports, &port->hmap_node); > > VLOG_INFO("destroyed port %s on bridge %s", port->name, br->name); > > @@ -4248,7 +4221,15 @@ port_from_dp_ifidx(const struct bridge *br, uint16_t > dp_ifidx) > static struct port * > port_lookup(const struct bridge *br, const char *name) > { > - return shash_find_data(&br->port_by_name, name); > + struct port *port; > + > + HMAP_FOR_EACH_WITH_HASH (port, hmap_node, hash_string(name, 0), > + &br->ports) { > + if (!strcmp(port->name, name)) { > + return port; > + } > + } > + return NULL; > } > > static struct iface * > @@ -4666,6 +4647,7 @@ static void > mirror_reconfigure(struct bridge *br) > { > unsigned long *rspan_vlans; > + struct port *port; > int i; > > /* Get rid of deleted mirrors. */ > @@ -4695,8 +4677,8 @@ mirror_reconfigure(struct bridge *br) > } > > /* Update port reserved status. */ > - for (i = 0; i < br->n_ports; i++) { > - br->ports[i]->is_mirror_output_port = false; > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > + port->is_mirror_output_port = false; > } > for (i = 0; i < MAX_MIRRORS; i++) { > struct mirror *m = br->mirrors[i]; > @@ -4768,11 +4750,11 @@ mirror_destroy(struct mirror *m) > { > if (m) { > struct bridge *br = m->bridge; > - size_t i; > + struct port *port; > > - for (i = 0; i < br->n_ports; i++) { > - br->ports[i]->src_mirrors &= ~(MIRROR_MASK_C(1) << m->idx); > - br->ports[i]->dst_mirrors &= ~(MIRROR_MASK_C(1) << m->idx); > + HMAP_FOR_EACH (port, hmap_node, &br->ports) { > + port->src_mirrors &= ~(MIRROR_MASK_C(1) << m->idx); > + port->dst_mirrors &= ~(MIRROR_MASK_C(1) << m->idx); > } > > shash_destroy(&m->src_ports); > @@ -4858,10 +4840,10 @@ mirror_reconfigure_one(struct mirror *m, struct > ovsrec_mirror *cfg) > struct shash src_ports, dst_ports; > mirror_mask_t mirror_bit; > struct port *out_port; > + struct port *port; > int out_vlan; > size_t n_vlans; > int *vlans; > - size_t i; > > /* Set name. */ > if (strcmp(cfg->name, m->name)) { > @@ -4898,10 +4880,9 @@ mirror_reconfigure_one(struct mirror *m, struct > ovsrec_mirror *cfg) > shash_init(&src_ports); > shash_init(&dst_ports); > if (cfg->select_all) { > - for (i = 0; i < m->bridge->n_ports; i++) { > - const char *name = m->bridge->ports[i]->name; > - shash_add_once(&src_ports, name, NULL); > - shash_add_once(&dst_ports, name, NULL); > + HMAP_FOR_EACH (port, hmap_node, &m->bridge->ports) { > + shash_add_once(&src_ports, port->name, NULL); > + shash_add_once(&dst_ports, port->name, NULL); > } > vlans = NULL; > n_vlans = 0; > @@ -4936,9 +4917,7 @@ mirror_reconfigure_one(struct mirror *m, struct > ovsrec_mirror *cfg) > > /* Update ports. */ > mirror_bit = MIRROR_MASK_C(1) << m->idx; > - for (i = 0; i < m->bridge->n_ports; i++) { > - struct port *port = m->bridge->ports[i]; > - > + HMAP_FOR_EACH (port, hmap_node, &m->bridge->ports) { > if (shash_find(&m->src_ports, port->name) > || (m->n_vlans > && (!port->vlan > -- > 1.7.1 > > _______________________________________________ > dev mailing list > [email protected] > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
