예제 #1
0
파일: rm.cpp 프로젝트: Shuriken13/Database
int RM_FileHandle::UpdateRec(RID &rid, RM_Record &rec) {
	int index;
	Bytes head = (Bytes)bpm->getPage(fileid, rid.GetPageid(), index);
	Bits* slots = new Bits(head, pernum);
	if (!slots->bit_get(rid.GetSlotid())) {
		//cout << "[RM_FileHandle-Update]Warning: RID doesn't exist,Maybe need Insert" << endl;
		return 1;
	}
	int offset = PAGE_HEAD_BYTE;
	offset = offset + recordsize * rid.GetSlotid();
	Bytes rlocation = (Bytes)head;
	rlocation = rlocation + offset;
	memcpy(rlocation, rec.GetRdata(), rec.GetSize());
	slots->bit_setone(rid.GetSlotid());

	bpm->markDirty(index);
	return 0;
}
예제 #2
0
파일: rm.cpp 프로젝트: Shuriken13/Database
int RM_FileHandle::InsertRec(RID &rid, RM_Record &rec) {		//这里的RID是插入后返回一个RID,其余成员函数都是需要一个RID

	int first_index;
	BufType first_head = bpm->getPage(fileid, 0, first_index);
	int empty_rid_offset = EMPTY_RID_OFFSET_BYTE;			//获取下一可插入项的偏移
	int next_page_offset = NEXT_EMPTY_PAGE_BYTE;			//获取下一个含空项页页码的偏移
	int slots_offset = SLOT_OFFSET_BYTE;					//获取slot偏移位置
	if (*(int*)(first_head + EMPTY_PAGE_OFFSET_4BYTE) != -1) {			//存在下一个空记录

		int insert_page_index;
		Bytes insert_page_head = (Bytes)bpm->getPage(fileid, first_head[EMPTY_PAGE_OFFSET_4BYTE], insert_page_index);
		bpm->markDirty(insert_page_index);						//肯定要修改,所以提前标记为脏页
		RID* current_empty_rid = (RID*)(insert_page_head + empty_rid_offset);	//下一可插入项
		int next_page = *(int*)(insert_page_head + next_page_offset);			//下一个含空项页页码
		Bits* slots = new Bits(insert_page_head + slots_offset, pernum);		//slots

		int offset = PAGE_HEAD_BYTE;
		offset = offset + recordsize * current_empty_rid->GetSlotid();
		Bytes rlocation = insert_page_head + offset;			//获取相应偏移后的地址
		memcpy(rlocation, rec.GetRdata(), rec.GetSize());			//插入该记录
		slots->bit_setone(current_empty_rid->GetSlotid());		//slot相应位子置1
		rid = *current_empty_rid;								//rid返回

		bool isfull = true;									//标记用,true表示当前页满
		for (int current_slot = current_empty_rid->GetSlotid() + 1; current_slot < pernum; current_slot++) {
			if (!slots->bit_get(current_slot)) {					//寻找下一个current_empty_rid,当slots[i]为0时说明该位为空
				isfull = false;
				current_empty_rid->SetSlotid(current_slot);		//修改下一个空项的位置
				break;
			}
		}
		if (isfull) {											//如果页满了
			first_head[EMPTY_PAGE_OFFSET_4BYTE] = next_page;	//当前数据页的下一页给第一页的含空项页
			bpm->markDirty(first_index);						//标记脏页
			current_empty_rid->SetSlotid(-1);					//slotid为-1表示没有下一项
			*(int*)(insert_page_head + next_page_offset) = -1;	//下一个含空项页页码表示当前页为满页
		}
	} else {													//均为满页,新建一页
		pagesum++;												//总页数新增一页
		first_head[PSIZE_OFFSET_4BYTE] = pagesum;				//修改总页数
		bpm->markDirty(first_index);							//标记为脏页
		int new_index;											//新建一个页,并将slot清零
		Bytes new_head = (Bytes)bpm->getPage(fileid, pagesum - 1, new_index);
		Bits* new_slots = new Bits(new_head + slots_offset, pernum);
		new_slots->all_zero();

		int new_offset = PAGE_HEAD_BYTE;						//slot[0]即为第一条记录,存储insert的记录
		Bytes rlocation = new_head + new_offset;
		memcpy(rlocation, rec.GetRdata(), rec.GetSize());
		new_slots->bit_setone(0);
		bpm->markDirty(new_index);								//标记为脏页

		RID new_rid;
		new_rid.SetFileid(-1);
		new_rid.SetPageid(pagesum - 1);
		new_rid.SetSlotid(1);
		*(RID*)(new_head + empty_rid_offset) = new_rid;			//下一可插入项更新为第1项
		rid = new_rid;
		rid.SetSlotid(0);
		first_head[EMPTY_PAGE_OFFSET_4BYTE] = pagesum - 1;		//第一页的含空项页设为当下的新增页
		*(int*)(new_head + next_page_offset) = -1;				//由于之前都是满页,这页显然没有后继页面,设为-1
	}
	return 0;
}