以下内容仅做记录,以备查看。

记录了sheepdog 最核心的算法和实现思路

//sheep分析记录


#define main_thread(type) struct { type __val; }

引用

-----------------------------------------------------------------------

md.c

========================================================================

struct disk {
	char path[PATH_MAX];  /*目录的路径名*/
	uint16_t nr_vdisks;
	uint64_t space;
};

struct vdisk {
	uint16_t idx;
	uint64_t id;
};

#define MD_MAX_DISK 64
#define MD_DEFAULT_VDISKS 128
#define MD_MAX_VDISK (MD_MAX_DISK * MD_DEFAULT_VDISKS)


static struct disk md_disks[MD_MAX_DISK];
static struct vdisk md_vds[MD_MAX_VDISK];
static int md_nr_disks; /* Protected by md_lock (当前添加的目录数)*/
static int md_nr_vds;   /*虚拟出来的vdisk个数


 /*重要函数 计算生成虚拟磁盘vdisk
uint64_t md_init_space(void)
{
    ...
		    calculate_vdisks(md_disks, md_nr_disks, total);     计算一个目录下有几个vdisk
	md_nr_vds = disks_to_vdisks(md_disks, md_nr_disks, md_vds);
   ...
}


 /*重要函数 计算填充vdisk的数据结构?
static inline int disks_to_vdisks(struct disk *ds, int nmds, struct vdisk *vds)
{
	struct disk *d_iter = ds;
	int i, j, nr_vdisks = 0;
	uint64_t hval;

	while (nmds--) {
		hval = FNV1A_64_INIT;

		for (i = 0; i < d_iter->nr_vdisks; i++) {
			hval = fnv_64a_buf(&nmds, sizeof(nmds), hval);
			for (j = strlen(d_iter->path) - 1; j >= 0; j--)
				hval = fnv_64a_buf(&d_iter->path[j], 1, hval);

			vds[nr_vdisks].id = hval;
			vds[nr_vdisks].idx = d_iter - ds;

			nr_vdisks++;
		}

		d_iter++;
	}
	xqsort(vds, nr_vdisks, vdisk_cmp);

	return nr_vdisks;
}


 /*oid 找vdisk,从而找块文件是否存在
static inline struct vdisk *oid_to_vdisk(uint64_t oid)
{
	return oid_to_vdisk_from(md_vds, md_nr_vds, oid);
}

 
 /*重要函数,映射oid都对应虚拟磁盘vdisk   (nr=md_nr_vds,vds=md_vds)*/
static struct vdisk *oid_to_vdisk_from(struct vdisk *vds, int nr, uint64_t oid) 

{
	uint64_t id = fnv_64a_buf(&oid, sizeof(oid), FNV1A_64_INIT);
	int start, end, pos;

	start = 0;
	end = nr - 1;

	if (id > vds[end].id || id < vds[start].id)
		return &vds[start];

	for (;;) {
		pos = (end - start) / 2 + start;
		if (vds[pos].id < id) {
			if (vds[pos + 1].id >= id)
				return &vds[pos + 1];
			start = pos;
		} else
			end = pos;
	}
}


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


group.c

=====================================================================================================

#define SD_DEFAULT_VNODES 64

#define SD_NODE_SIZE 56

/*节点数据结构
struct sd_node {
	struct node_id  nid;
	uint16_t	nr_vnodes;
	uint32_t	zone;          /* use last 4 bytes as zone id
		                       uint8_t *b = sys->this_node.nid.addr + 12;
		                       sys->this_node.zone = b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 */
	uint64_t        space;
};

/*虚拟节点数据结构
struct sd_vnode {
	struct node_id  nid;
	uint16_t	node_idx;
	uint32_t	zone;
	uint64_t        id;
};


struct vnode_info {
	struct sd_vnode vnodes[SD_MAX_VNODES];
	int nr_vnodes;

	struct sd_node nodes[SD_MAX_NODES];
	int nr_nodes;

	int nr_zones;
	refcnt_t refcnt;
};



 /*重要,计算有好多个vnode,已经vnode对应的服务器地址
struct vnode_info *alloc_vnode_info(const struct sd_node *nodes,
				    size_t nr_nodes)
{
	...
	recalculate_vnodes(vnode_info->nodes, nr_nodes);

	vnode_info->nr_vnodes = nodes_to_vnodes(vnode_info->nodes, nr_nodes,
						vnode_info->vnodes);
	vnode_info->nr_zones = get_zones_nr_from(nodes, nr_nodes);
	refcount_set(&vnode_info->refcnt, 1);
	return vnode_info;
}


 /*特别重要 计算每个服务器对应的vnode个数,一般恒定64个(由recalculate_vnodes函数计算并由SD_DEFAULT_VNODES指定)
static inline int nodes_to_vnodes(struct sd_node *nodes, int nr,
				  struct sd_vnode *vnodes)
{
	struct sd_node *n = nodes;
	int i, j, nr_vnodes = 0;
	uint64_t hval;

	while (nr--) {
		hval = FNV1A_64_INIT;

		for (i = 0; i < n->nr_vnodes; i++) {
			if (vnodes) {
				hval = fnv_64a_buf(&n->nid.port, sizeof(n->nid.port), hval);
				for (j = ARRAY_SIZE(n->nid.addr) - 1; j >= 0; j--)
					hval = fnv_64a_buf(&n->nid.addr[j], 1, hval);

				vnodes[nr_vnodes].id = hval;
				memcpy(vnodes[nr_vnodes].nid.addr, n->nid.addr, sizeof(n->nid.addr));
				vnodes[nr_vnodes].nid.port = n->nid.port;
				vnodes[nr_vnodes].node_idx = n - nodes;
				vnodes[nr_vnodes].zone = n->zone;
			}

			nr_vnodes++;
		}

		n++;
	}

	if (vnodes)
		xqsort(vnodes, nr_vnodes, vnode_cmp);

	return nr_vnodes;
}