首先了解什么是位图和他的工作原理。
定义:
位图就是bitmap的缩写,所谓bitmap,就是用每一位来存放某种状态,适用于大规模数据,该数据都是不重复的简单数据。通常是用来判断某个数据存不存在的。
工作原理:
查找一个数是否存在,其实答案就是存在或者不存在,这种只需要回答是与否的问题,我们都可以用二进制中的位来表示,1表示该数存在,反之0表示该数不存在。位图中的每个数据单元都是一个bit位,这样子平时我们都要话32位4字节来存储数据,而现在我们只需要花1个字节就能“存储数据”,在空间上减少了约32倍的容量。例如40G的数据我们只要花1.3G来存储。但是我们平时操作的数据类型最小就是一个字节,我们不能直接对位进行操作,所以我们可以借助位运算来对数据进行操作。(摘录)
实现:
用基于peer to peer协议的下载系统进行举例子:
定义一个全局变量bitmap指向自己的位图,可以从位图中获知下载的进度,创建下载文件的位图,分配内存并初始化,获取某一位的值,设置某一位的值,将位图所有位全部清零,然后全部设置成1,释放本部分代码中动态分配的内存,将位图存储到文件中,在下次下载时,先读取该文件获取已经下载的进度,断点续传,判断src(源)位图的peer对具有dst(目的)位图的peer是否感兴趣,如果dst(目的)中某位为1而src(源)对应为0,则说明src(源)对dst(目的)感兴趣,如果感兴趣,就获取当前已下载到的总piece数,继续进行下载。
部分代码
//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
整体代码就不赘述出来了。