现在的位置: 首页 > 综合 > 正文

Bitmap分析

2014年09月05日 ⁄ 综合 ⁄ 共 2333字 ⁄ 字号 评论关闭

在bitmap中用一位来表示page是否被占用,1表示被占用,0表示没被占用,计算机里面处理的位数最少的变量是byte,所以也就是8位做为一个整体来对待,8位表示的整数是从0到255,

firstHoleSize [] lastHoleSize [] maxHoleSize [] maxHoleOffset [] 是四个固定的数组,每个数组都有256个元素,对应从0到255的整数,每个整数的二进制代表的页面被占用情况

举例来说: 00001010 代表十进制的10

firstHoleSize [] 表示从右到左的,未被占用的页面有多少个,只要末位为是1,那么肯定没有hole,所以奇数全为0,firstHoleSize [10] = 1

lastHoleSize [] ,表示从左到右,未被占用的页面多少个,只要最左位为1,那是肯定没有hole,所以大于128的全是0, lastHoleSize [10] = 4

 

maxHoleSize [] ,表示连续的最大的Hole是多少个页面,maxHoleSize [10] = 4

maxHoleOffset [] 是和 maxHoleSize [] 一起使用的,表示从左到右,最大的Hole的位置,maxHoleOffset [10] = 4

 

const size_t dbAllocationQuantumBits = 4;
const size_t dbAllocationQuantum = 1 << dbAllocationQuantumBits;
const size_t dbPageBits = 12;
const size_t dbPageSize = 1 << dbPageBits;
const size_t dbIdsPerPage = dbPageSize / sizeof(oid_t);
const size_t dbHandlesPerPage = dbPageSize / sizeof(offs_t);
const size_t dbHandleBits = 1 + sizeof(offs_t)/4; // log(sizeof(offs_t))
const size_t dbBitmapSegmentBits = dbPageBits + 3 + dbAllocationQuantumBits;
const size_t dbBitmapSegmentSize = 1 << dbBitmapSegmentBits;
const size_t dbBitmapPages = 1 << (dbDatabaseOffsetBits-dbBitmapSegmentBits);
const size_t dbDirtyPageBitmapSize = 1 << (dbDatabaseOidBits-dbPageBits+dbHandleBits-3);

在fastdb中,bitmap中的每一位,表示两个字节,就是16位:

const size_t dbAllocationQuantumBits = 4;
const size_t dbAllocationQuantum = 1 << dbAllocationQuantumBits;

每一个page中,有4096个byte,:

const size_t dbPageBits = 12;
const size_t dbPageSize = 1 << dbPageBits;

每个bitmap的page,能表示的存储空间总数量为2的(12 + 3 + 4)次幂:

const size_t dbBitmapSegmentBits = dbPageBits + 3 + dbAllocationQuantumBits;
const size_t dbBitmapSegmentSize = 1 << dbBitmapSegmentBits

在32位的系统中(dbDatabaseOffsetBits = 32),所需要的bitmap的总的page数就为,2的32次幂除以上面那个数,也就是8192个页面,

const size_t dbBitmapPages = 1 << (dbDatabaseOffsetBits-dbBitmapSegmentBits);

fast在初始化过程中,默认了8K的bitmap页面,但并没有实际的分配,只是指定了个数

在内存中还存在一个结构,用来保存在事务过程中哪个页面被修改了,也是用bitmap来实现的,它需要页面的总个数,对于32位的系统,每个页面是12位,每个字节可表示8位,(每个oid须用四位表示,或是每个页面只能存dbIdsPerPage 个oid),这个部分主要是从oid到页面的快速变换:

const size_t dbDirtyPageBitmapSize = 1 << (dbDatabaseOidBits-dbPageBits+dbHandleBits-3);

class dbMonitor {

。。。。。。。

int4 dirtyPagesMap[dbDirtyPageBitmapSize/4];

。。。。。。

一起使用

 

在空间的分配时,先看看是不是有以前释放的满足要求,没有的话就从未分配的分配,分配函数只要把前面几个宏定义和数组看明白,还是比较好理解的,主要就是修改bitmap里面字节的每一位

bitmap里面的每一位,代表硬盘上一个16字节的空间是否被使用,不是一个4096个字节的页面,

代表页面的只有是否表示页面被修改过的另一个结构,dbMonitor->dirtyPagesMap[],不要搞混,

 

 

 

在数据库运行一段时间后,bitmap中和页面将变得不再连续,因为不停的拷贝造成的,index 和 shadowIndex还是连续的

在每次修改bitmap之前,会把它拷贝一份,在拷贝的那份上修改,

拷贝主要是在dbRecord* putRow(oid_t oid) 和 byte* put(oid_t oid) 这两个函数里面实现的,名字比较怪

抱歉!评论已关闭.