From: MORITA Kazutaka <[email protected]> This introduces wrappers around qsort and bsearch to make them type safe.
Signed-off-by: MORITA Kazutaka <[email protected]> --- v2: - rename typesafe_qsort and typesafe_bsearch with xqsort and xbsearch include/sheep.h | 25 +++++++++++++------------ include/util.h | 15 +++++++++++++++ lib/event.c | 8 ++++---- sheep/cluster/zookeeper.c | 2 +- sheep/group.c | 8 +++----- sheep/md.c | 7 ++----- sheep/ops.c | 7 +++---- sheep/recovery.c | 13 +++++-------- 8 files changed, 46 insertions(+), 39 deletions(-) diff --git a/include/sheep.h b/include/sheep.h index 456fd07..e917064 100644 --- a/include/sheep.h +++ b/include/sheep.h @@ -233,13 +233,10 @@ static inline const char *sd_strerror(int err) return descs[err]; } -static inline int node_id_cmp(const void *a, const void *b) +static inline int node_id_cmp(const struct node_id *node1, + const struct node_id *node2) { - const struct node_id *node1 = a; - const struct node_id *node2 = b; - int cmp; - - cmp = memcmp(node1->addr, node2->addr, sizeof(node1->addr)); + int cmp = memcmp(node1->addr, node2->addr, sizeof(node1->addr)); if (cmp != 0) return cmp; @@ -250,16 +247,20 @@ static inline int node_id_cmp(const void *a, const void *b) return 0; } -static inline bool node_eq(const struct sd_node *a, const struct sd_node *b) +static inline int node_cmp(const struct sd_node *node1, + const struct sd_node *node2) { - return node_id_cmp(&a->nid, &b->nid) == 0; + return node_id_cmp(&node1->nid, &node2->nid); } -static inline int vnode_cmp(const void *a, const void *b) +static inline bool node_eq(const struct sd_node *a, const struct sd_node *b) { - const struct sd_vnode *node1 = a; - const struct sd_vnode *node2 = b; + return node_cmp(a, b) == 0; +} +static inline int vnode_cmp(const struct sd_vnode *node1, + const struct sd_vnode *node2) +{ if (node1->id < node2->id) return -1; if (node1->id > node2->id) @@ -297,7 +298,7 @@ static inline int nodes_to_vnodes(struct sd_node *nodes, int nr, } if (vnodes) - qsort(vnodes, nr_vnodes, sizeof(*vnodes), vnode_cmp); + xqsort(vnodes, nr_vnodes, vnode_cmp); return nr_vnodes; } diff --git a/include/util.h b/include/util.h index 68eface..1603796 100644 --- a/include/util.h +++ b/include/util.h @@ -98,6 +98,21 @@ void untrim_zero_sectors(void *buf, uint64_t offset, uint32_t len, uint32_t requested_len); int atomic_create_and_write(const char *path, char *buf, size_t len); +/* a type safe version of qsort() */ +#define xqsort(base, nmemb, compar) \ +({ \ + assert(compar(base, base) == 0); \ + qsort(base, nmemb, sizeof(*(base)), (comparison_fn_t)compar); \ +}) + +/* a type safe version of bsearch() */ +#define xbsearch(key, base, nmemb, compar) \ +({ \ + (void) (key == base); \ + assert(compar(base, base) == 0); \ + bsearch(key, base, nmemb, sizeof(*(base)), (comparison_fn_t)compar); \ +}) + #ifdef assert #undef assert #endif diff --git a/lib/event.c b/lib/event.c index becacd7..3f29d97 100644 --- a/lib/event.c +++ b/lib/event.c @@ -171,12 +171,12 @@ void event_force_refresh(void) event_loop_refresh = true; } -static int epoll_event_cmp(const void *_a, const void *_b) +static int epoll_event_cmp(const struct epoll_event *_a, struct epoll_event *_b) { struct event_info *a, *b; - a = (struct event_info *)((struct epoll_event *)_a)->data.ptr; - b = (struct event_info *)((struct epoll_event *)_b)->data.ptr; + a = (struct event_info *)_a->data.ptr; + b = (struct event_info *)_b->data.ptr; /* we need sort event_info array in reverse order */ if (a->prio < b->prio) @@ -194,7 +194,7 @@ static void do_event_loop(int timeout, bool sort_with_prio) refresh: nr = epoll_wait(efd, events, nr_events, timeout); if (sort_with_prio) - qsort(events, nr, sizeof(struct epoll_event), epoll_event_cmp); + xqsort(events, nr, epoll_event_cmp); if (nr < 0) { if (errno == EINTR) diff --git a/sheep/cluster/zookeeper.c b/sheep/cluster/zookeeper.c index 648bb7a..1cd39f7 100644 --- a/sheep/cluster/zookeeper.c +++ b/sheep/cluster/zookeeper.c @@ -85,7 +85,7 @@ static struct zk_node *zk_tree_insert(struct zk_node *new) parent = *p; entry = rb_entry(parent, struct zk_node, rb); - cmp = node_id_cmp(&new->node.nid, &entry->node.nid); + cmp = node_cmp(&new->node, &entry->node); if (cmp < 0) p = &(*p)->rb_left; else if (cmp > 0) diff --git a/sheep/group.c b/sheep/group.c index 8fce4c6..700e49f 100644 --- a/sheep/group.c +++ b/sheep/group.c @@ -130,8 +130,7 @@ bool have_enough_zones(void) static int get_node_idx(struct vnode_info *vnode_info, struct sd_node *ent) { - ent = bsearch(ent, vnode_info->nodes, vnode_info->nr_nodes, - sizeof(*ent), node_id_cmp); + ent = xbsearch(ent, vnode_info->nodes, vnode_info->nr_nodes, node_cmp); if (!ent) return -1; @@ -188,7 +187,7 @@ struct vnode_info *alloc_vnode_info(const struct sd_node *nodes, vnode_info->nr_nodes = nr_nodes; memcpy(vnode_info->nodes, nodes, sizeof(*nodes) * nr_nodes); - qsort(vnode_info->nodes, nr_nodes, sizeof(*nodes), node_id_cmp); + xqsort(vnode_info->nodes, nr_nodes, node_cmp); recalculate_vnodes(vnode_info->nodes, nr_nodes); @@ -578,8 +577,7 @@ static int cluster_wait_for_join_check(const struct sd_node *joined, sd_eprintf("joining node epoch too small: %" PRIu32 " vs %" PRIu32, jm->epoch, local_epoch); - if (bsearch(joined, local_entries, nr_local_entries, - sizeof(struct sd_node), node_id_cmp)) + if (xbsearch(joined, local_entries, nr_local_entries, node_cmp)) return CJ_RES_FAIL; return CJ_RES_JOIN_LATER; } diff --git a/sheep/md.c b/sheep/md.c index 14d563d..66abe79 100644 --- a/sheep/md.c +++ b/sheep/md.c @@ -82,11 +82,8 @@ static struct vdisk *oid_to_vdisk_from(struct vdisk *vds, int nr, uint64_t oid) } } -static int vdisk_cmp(const void *a, const void *b) +static int vdisk_cmp(const struct vdisk *d1, const struct vdisk *d2) { - const struct vdisk *d1 = a; - const struct vdisk *d2 = b; - if (d1->id < d2->id) return -1; if (d1->id > d2->id) @@ -116,7 +113,7 @@ static inline int disks_to_vdisks(struct disk *ds, int nmds, struct vdisk *vds) d_iter++; } - qsort(vds, nr_vdisks, sizeof(*vds), vdisk_cmp); + xqsort(vds, nr_vdisks, vdisk_cmp); return nr_vdisks; } diff --git a/sheep/ops.c b/sheep/ops.c index 8ab9ac3..90ec241 100644 --- a/sheep/ops.c +++ b/sheep/ops.c @@ -687,12 +687,12 @@ static int cluster_recovery_completion(const struct sd_req *req, * to send notification */ for (i = 0; i < nr_recovereds; i++) - if (!node_id_cmp(&node->nid, &recovereds[i].nid)) { + if (!node_cmp(node, recovereds + i)) { sd_dprintf("duplicate %s", node_to_str(node)); return SD_RES_SUCCESS; } recovereds[nr_recovereds++] = *node; - qsort(recovereds, nr_recovereds, sizeof(*recovereds), node_id_cmp); + xqsort(recovereds, nr_recovereds, node_cmp); sd_dprintf("%s is recovered at epoch %d", node_to_str(node), epoch); for (i = 0; i < nr_recovereds; i++) @@ -705,8 +705,7 @@ static int cluster_recovery_completion(const struct sd_req *req, if (vnode_info->nr_nodes == nr_recovereds) { for (i = 0; i < nr_recovereds; ++i) { - if (node_id_cmp(&vnode_info->nodes[i].nid, - &recovereds[i].nid)) + if (node_cmp(vnode_info->nodes + i, recovereds + i)) break; } if (i == nr_recovereds) { diff --git a/sheep/recovery.c b/sheep/recovery.c index 20e930f..fb2df3b 100644 --- a/sheep/recovery.c +++ b/sheep/recovery.c @@ -89,12 +89,10 @@ static void queue_recovery_work(struct recovery_info *rinfo); #define DEFAULT_LIST_BUFFER_SIZE (UINT64_C(1) << 22) static size_t list_buffer_size = DEFAULT_LIST_BUFFER_SIZE; -static int obj_cmp(const void *oid1, const void *oid2) +static int obj_cmp(const uint64_t *oid1, const uint64_t *oid2) { - const uint64_t hval1 = fnv_64a_buf((void *)oid1, sizeof(uint64_t), - FNV1A_64_INIT); - const uint64_t hval2 = fnv_64a_buf((void *)oid2, sizeof(uint64_t), - FNV1A_64_INIT); + const uint64_t hval1 = fnv_64a_buf(oid1, sizeof(*oid1), FNV1A_64_INIT); + const uint64_t hval2 = fnv_64a_buf(oid2, sizeof(*oid2), FNV1A_64_INIT); if (hval1 < hval2) return -1; @@ -713,8 +711,7 @@ static void screen_object_list(struct recovery_list_work *rlw, for (j = 0; j < nr_objs; j++) { if (!vnode_is_local(vnodes[j])) continue; - if (bsearch(&oids[i], rlw->oids, old_count, - sizeof(uint64_t), obj_cmp)) + if (xbsearch(&oids[i], rlw->oids, old_count, obj_cmp)) continue; rlw->oids[rlw->count++] = oids[i]; @@ -728,7 +725,7 @@ static void screen_object_list(struct recovery_list_work *rlw, } } - qsort(rlw->oids, rlw->count, sizeof(uint64_t), obj_cmp); + xqsort(rlw->oids, rlw->count, obj_cmp); } /* Prepare the object list that belongs to this node */ -- 1.7.9.5 -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
