[sheepdog] [PATCH] sheep: refactor get_nth_node() and get_vnode_pos()

Yunkai Zhang yunkai.me at gmail.com
Sat Aug 4 12:17:19 CEST 2012


From: Yunkai Zhang <qiushu.zyk at taobao.com>

oid_to_sheeps() calls get_nth_node() in a for-loop, but get_nth_node()
will do duplicated works because it should find [0..(n-2)] vnodes indexs
before it try to calculate n'th vnode index.

The return value of get_vnode_pos() seems werid for user, it need to plus one
before we can use it.

This patch try to refactor these two functions:
1) split a new function named get_vnode_next_idx() from get_nth_node().
2) rename get_vnode_pos() to get_vnode_first_idx(), and make the return
   value can be used directly.
3) rename get_nth_node() to get_vnode_nth_idx() which will be more descriptive.

Signed-off-by: Yunkai Zhang <qiushu.zyk at taobao.com>
---
 include/sheep.h | 101 ++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 62 insertions(+), 39 deletions(-)

diff --git a/include/sheep.h b/include/sheep.h
index 5795111..1d07b23 100644
--- a/include/sheep.h
+++ b/include/sheep.h
@@ -60,32 +60,9 @@ static inline int same_zone(struct sd_vnode *e, int n1, int n2)
 	return e[n1].zone != 0 && e[n1].zone == e[n2].zone;
 }
 
-/* traverse the virtual node list and return the n'th one */
-static inline int get_nth_node(struct sd_vnode *entries,
-			       int nr_entries, int base, int n)
-{
-	int nodes[SD_MAX_REDUNDANCY];
-	int nr = 0, idx = base, i;
-
-	while (n--) {
-		nodes[nr++] = idx;
-next:
-		idx = (idx + 1) % nr_entries;
-		if (idx == base) {
-			panic("bug"); /* not found */
-		}
-		for (i = 0; i < nr; i++) {
-			if (same_zone(entries, idx, nodes[i]))
-				/* this node is in the same zone, so skip here */
-				goto next;
-		}
-	}
-
-	return idx;
-}
-
-static inline int get_vnode_pos(struct sd_vnode *entries,
-			int nr_entries, uint64_t oid)
+/* Get the first vnode's index which is matching the OID */
+static inline int get_vnode_first_idx(struct sd_vnode *entries, int nr_entries,
+				      uint64_t oid)
 {
 	uint64_t id = fnv_64a_buf(&oid, sizeof(oid), FNV1A_64_INIT);
 	int start, end, pos;
@@ -94,36 +71,82 @@ static inline int get_vnode_pos(struct sd_vnode *entries,
 	end = nr_entries - 1;
 
 	if (id > entries[end].id || id < entries[start].id)
-		return end;
+		return (end + 1) % nr_entries;
 
 	for (;;) {
 		pos = (end - start) / 2 + start;
 		if (entries[pos].id < id) {
 			if (entries[pos + 1].id >= id)
-				return pos;
+				return (pos + 1) % nr_entries;
 			start = pos;
 		} else
 			end = pos;
 	}
 }
 
-static inline int obj_to_sheep(struct sd_vnode *entries,
-			       int nr_entries, uint64_t oid, int idx)
+/* Get next vnode's index according to the PREV_IDXS */
+static inline int get_vnode_next_idx(struct sd_vnode *entries, int nr_entries,
+				     int *prev_idxs, int nr_prev_idxs)
 {
-	int pos = get_vnode_pos(entries, nr_entries, oid);
+	int i, found, idx, first_idx;
+
+	first_idx = prev_idxs[0];
+	idx = prev_idxs[nr_prev_idxs - 1];
+	for (;;) {
+		idx = (idx + 1) % nr_entries;
+		if (idx == first_idx)
+			panic("can't find next new idx\n");
+
+		for (found = 0, i = 0; i < nr_prev_idxs; i++) {
+			if (same_zone(entries, idx, prev_idxs[i])) {
+				found = 1;
+				break;
+			}
+		}
 
-	return get_nth_node(entries, nr_entries, (pos + 1) % nr_entries, idx);
+		if (!found)
+			return idx;
+	}
+}
+
+/* Get the n'th vnode's index which is matching the OID */
+static inline int get_vnode_nth_idx(struct sd_vnode *entries,
+			int nr_entries, uint64_t oid, int nth)
+{
+	int nr_idxs = 0, idxs[SD_MAX_REDUNDANCY];
+
+	idxs[nr_idxs++] = get_vnode_first_idx(entries, nr_entries, oid);
+
+	if (!nth)
+		return idxs[nth];
+
+	while (nr_idxs <= nth) {
+		idxs[nr_idxs] = get_vnode_next_idx(entries, nr_entries,
+						     idxs, nr_idxs);
+		nr_idxs++;
+	}
+
+	return idxs[nth];
 }
 
-static inline void obj_to_sheeps(struct sd_vnode *entries,
-		  int nr_entries, uint64_t oid, int nr_copies, int *idxs)
+static inline int obj_to_sheep(struct sd_vnode *entries, int nr_entries,
+			       uint64_t oid, int nth_idx)
 {
-	int pos = get_vnode_pos(entries, nr_entries, oid);
-	int idx;
+	return get_vnode_nth_idx(entries, nr_entries, oid, nth_idx);
+}
 
-	for (idx = 0; idx < nr_copies; idx++)
-		idxs[idx] = get_nth_node(entries, nr_entries,
-				(pos + 1) % nr_entries, idx);
+static inline void obj_to_sheeps(struct sd_vnode *entries, int nr_entries,
+				 uint64_t oid, int nr_copies, int *idxs)
+{
+	int nr_idxs = 0;
+
+	idxs[nr_idxs++] = get_vnode_first_idx(entries, nr_entries, oid);
+
+	while (nr_idxs < nr_copies) {
+		idxs[nr_idxs] = get_vnode_next_idx(entries, nr_entries,
+						     idxs, nr_idxs);
+		nr_idxs++;
+	}
 }
 
 static inline const char *sd_strerror(int err)
-- 
1.7.11.2




More information about the sheepdog mailing list