예제 #1
0
파일: rm.cpp 프로젝트: Shuriken13/Database
int RM_FileScan::NextRec(RM_Record &rec, RID &rid) {
	if (isclose) {
		//cout << "[RM_FileScan]GetNextRec error: This filescan has been closed!" << endl;
		return 2;
	}
	//NULL1:当comparevalue为NULL且op为大小于中的一个时为用假,返回为空
	if(op <= GE && op >= LT && comparevalue == NULL)	return 1;

	bool get_flag = false;
	int index;
	Bytes head = (Bytes)filehandle->bpm->getPage(currentRid->GetFileid(), currentRid->GetPageid(), index);
	Bits* slots = new Bits(head, filehandle->GetPnum());
	Bytes record_head;
	int current_slotid = currentRid->GetSlotid();
	int current_pageid = currentRid->GetPageid();

	int offset = PAGE_HEAD_BYTE;
	while (!get_flag) {
//		cout << "fuck1" << endl;
		while ( current_slotid < filehandle->GetPnum() && slots->bit_get(current_slotid) == false) {
			current_slotid++;
		}
//		cout << "fuck2" << endl;
		if (current_slotid == filehandle->GetPnum()) {		//该页记录已全部遍历
			current_pageid++;
			current_slotid = 0;
			if (current_pageid == filehandle->GetPsum()) {	//说明该文件下所有页的所有记录都已遍历过.此时返回0表示已遍历完
				currentRid->SetPageid(current_pageid);
				currentRid->SetSlotid(current_slotid);
				return 1;
			}
			head = (Bytes)filehandle->bpm->getPage(currentRid->GetFileid(), current_pageid, index);
			slots->setData(head);
			offset = PAGE_HEAD_BYTE;
		} else {	//得到一个记录
//			cout << "fuck3" << endl;
			offset = PAGE_HEAD_BYTE;
			offset = offset + filehandle->GetRsize() * current_slotid;
			record_head = head + offset;
			int nullbits_offset = RECORD_NULLBITS_OFFSET_BYTE;
			Bits* nullbits = new Bits(record_head + nullbits_offset, attrcol+1);		//获取相应记录的null位图(一定长度)
			//NULL2.1:左边NULL且需要判等(不等),则直接通过null位图来判别
			//NULL2.2:左边NULL且op为大小于,直接返回true
//			cout << "fuck3.1" << endl;
			if(nullbits->bit_get(attrcol) == 0) {//左边为NULL
				if(op == NO) {
					get_flag = true;
				}
				if(op <= GE && op >= LT) {		//为理解方便写出来,实际没什么用
					get_flag = false;
				}
				if(op == EQ) {
					get_flag = (comparevalue == NULL);
				}
				if(op == NE) {
					get_flag = !(comparevalue == NULL);
				}
			} else /*if (comparevalue != 0)*/{//其他情况,进行相应比较
//				cout << "fuck3.2" << endl;
				char* value_head = record_head + attroffset;
//				enum AttrType{INTEGER,FLOAT,STRING};
//				enum CompOp{EQ,LT,GT,LE,GE,NE,NO};
//				cout << "11" << endl;
				const char* cmp1 = value_head;
				const char* cmp2 = (char*)comparevalue;
				const CompOp cmpop = op;
				const AttrType cmptype = type;
//				cout << "22" << endl;
				if  (comparevalue != 0 || op == NO){
//					cout << "33" << endl;
					get_flag = compareData(cmp1, cmpop, cmp2, cmptype);
				}
				else
					get_flag = false;

			}
//			cout << "fuck4" << endl;
			if (get_flag) {
				rec.SetSize(filehandle->GetRsize());
//				cout << "get_data: " << &get_data << " " << "head: " << &record_head << endl;
				rec.SetData(record_head);
			} else {
				current_slotid++;
			}
//			cout << "fuck5" << endl;
		}
	}
	//设置RID
	rid.SetFileid(-1);
	rid.SetPageid(current_pageid);
	rid.SetSlotid(current_slotid);
	//设置下一条记录的位置
	currentRid->SetPageid(current_pageid);
	currentRid->SetSlotid(current_slotid + 1);
	return 0;
}