位图管理模块的设计和实现
对位图的操作主要在bitfield.h和bitfield.c中,负责创建位图,设置和获取位图某一位的值,保存位图等操作。
//bitfield.h
#ifndef BITFIELD_H
#define BITFIELD_H
typedef struct _Bitmap
{
unsigned char *bitfield; //保存位图
int bitfield_length; //位图所占总字节数
int valid_length; //位图有效的总位数,每一位代表一个piece
} Bitmap;
int create_bitfield(); //创建位图,分配内存并进行初始化
int get_bit_value(Bitmap *bitmap, int index);//获取某一位的值
int set_bit_value(Bitmap *bitmap, int index, unsigned char value);//设置某一位的值
int all_zero(Bitmap *bitmap); //全部清零
int all_set(Bitmap *bitmap); //全部设置为1
void release_memory_in_bitfield(); //释放bitfield.c中动态分配的空间
int printf_bitfield(Bitmap *bitmap); //打印位图值,用于调试
int restore_bitmap(); //将位图存储到文件中
//在下次下载时,先读取该文件获取已经下载的进度
int is_interested(Bitmap *dst, Bitmap *src); //拥有位图src的peer是否对拥有
//dst位图的peer感兴趣
int get_download_piece_num(); //获取当前已下载到的总piece数
#endif // BITFIELD_H
程序说明:结构体Bitmap中,bitfield_length是指针bitfield所指向的内存空间的长度(单位B),而valid_length是位图的有效位数。如:一位图在100B,而有效数位795,那么最后一个字节的最后5位是无效的。
函数is_interested用于判断两个peer是否感兴趣,如果peer1拥有某个piece,而peer2没有,则peer2对peer1感兴趣,希望从peer1出下载它没有的piece。
函数get_download_piece_num用于获取已下载的piece数,其方法是统计结构体Bitmap的bitfield成员所指向的内存中值为1的位数。
文件bitfield.c的头部如下:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <malloc.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "parse_metafile.h"
#include "bitfield.h"
extern int pieces_length; //pieces缓冲区的长度
extern char *file_name; //对于单文件,存放