[sheepdog] [PATCH v2] make qsort and bsearch type safe
MORITA Kazutaka
morita.kazutaka at gmail.com
Thu May 16 07:11:22 CEST 2013
From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
This introduces wrappers around qsort and bsearch to make them type
safe.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
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
More information about the sheepdog
mailing list