Пример #1
0
int RM_FileScan::GetNextRec(RM_Record &rec, RID &rid) {
	RM_Record nextrec;
	int result = NextRec(nextrec, rid);
	if(result != 0) return result;
	Bytes get_data = new char[filehandle->GetRsize()];
	memcpy(get_data,nextrec.GetRdata(),filehandle->GetRsize());
	rec.SetSize(filehandle->GetRsize());
	rec.SetData(get_data);
	return 0;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
void test_QM() {

    int attrcount = 4;
    AttrInfo attrlist[4];
    char aname1[] = "id";
    char aname2[] = "age";
    char aname3[] = "gender";
    char aname4[] = "nationality";

    strcpy(attrlist[0].attrName, aname1);
    strcpy(attrlist[1].attrName, aname2);
    strcpy(attrlist[2].attrName, aname3);
    strcpy(attrlist[3].attrName, aname4);

    attrlist[0].attrLenth = 8;
    attrlist[1].attrLenth = 8;
    attrlist[2].attrLenth = 8;
    attrlist[3].attrLenth = 15;

    attrlist[0].attrType = INTEGER;
    attrlist[1].attrType = INTEGER;
    attrlist[2].attrType = INTEGER;
    attrlist[3].attrType = STRING;
    attrlist[0].notNull = true;
    attrlist[1].notNull = false;
    attrlist[2].notNull = true;
    attrlist[3].notNull = true;

    FileManager* fm = new FileManager();
    BufPageManager* bpm = new BufPageManager(fm);
    RM_Manager* rmm = new RM_Manager(bpm);
    IX_Manager* ixm = new IX_Manager();
    SM_Manager* smm = new SM_Manager(rmm, ixm, currentdb, dbIsOpen);
    QL_Manager* qlm = new QL_Manager(smm, ixm, rmm, currentdb, dbIsOpen);

    string db1 = "db1";
    string db2 = "db2";
    string db3 = "db3";

    string table1 = "table1";
    string table2 = "table2";
    string table3 = "table3";

    smm->createDb(db1);
    smm->createDb(db2);

    smm->useDb(db1);
    smm->createTable(table1, 4, attrlist, -1);
    smm->createTable(table2, 4, attrlist, -1);

    cout << endl << "test insert----------------------" << endl;
    int nValues = 4;
    Value *values = new Value[nValues];

	for (long long i = 1; i < 10; ++i) {
		cout << "id = " << i << endl;
		long long id = i;
		long long age1 = 10 - i;
		long long gender1 = i + 15;
		char nationality1[] = "China";

		values[0].type = INTEGER;
		values[0].data = (void *) (&id);
		values[1].type = INTEGER;
		values[1].data = (void *) (&age1);
		values[2].type = INTEGER;
		values[2].data = (void *) (&gender1);
		values[3].type = STRING;
		values[3].data = (void *) nationality1;
		if(qlm->Insert(table1, nValues, values) != 0){
			cout << "insert table1 failed" << endl;
		}
	}
	int nValues2 = 4;
	Value *values2 = new Value[nValues2];
	for (long long i = 1; i < 10; ++i) {
		cout << "id = " << i << endl;
		long long id = i+1;
		long long age1 = 15 - i;
		long long gender1 = i + 60;
		char nationality1[] = "China";

		values2[0].type = INTEGER;
		values2[0].data = (void *) (&id);
		values2[1].type = INTEGER;
		values2[1].data = (void *) (&age1);
		values2[2].type = INTEGER;
		values2[2].data = (void *) (&gender1);
		values2[3].type = STRING;
		values2[3].data = (void *) nationality1;
		if (qlm->Insert(table2, nValues2, values2) != 0) {
			cout << "insert table1 failed" << endl;
		}
	}

	cout << endl << "test delete----------------------" << endl;
	WhereNode *whereExpr2 = new WhereNode;
	whereExpr2->type = CONDITION;
	Condition condition2;
	condition2.lhsAttr.relName = table1; condition2.lhsAttr.attrName = "id";
	condition2.op = LE;
	condition2.bRhsIsAttr = 0;
	double id_delete2 = 3;
	condition2.rhsValue.type = FLOAT; condition2.rhsValue.data = (void *)(&id_delete2);
	whereExpr2->pData = (void *)(&condition2);
	whereExpr2->lc = NULL; whereExpr2->rc = NULL;

	WhereNode *whereExpr3 = new WhereNode;
	whereExpr3->type = CONDITION;
	Condition condition3;
	condition3.lhsAttr.relName = table1; condition3.lhsAttr.attrName = "age";
	condition3.op = LE;
	condition3.bRhsIsAttr = 0;
	double id_delete3 = 3;
	condition3.rhsValue.type = FLOAT; condition3.rhsValue.data = (void *)(&id_delete3);
	whereExpr3->pData = (void *)(&condition3);
	whereExpr3->lc = NULL; whereExpr3->rc = NULL;

	WhereNode *whereExpr1 = new WhereNode;
	whereExpr1->type = LOGIC_OP;
	LogicOp logic_op = OR;
	whereExpr1->pData = (void *)(&logic_op);
	whereExpr1->lc = whereExpr2;
	whereExpr1->rc = whereExpr3;

	WhereNode *whereExpr5 = new WhereNode;
	whereExpr5->type = CONDITION;
	Condition condition5;
	condition5.lhsAttr.relName = table1; condition5.lhsAttr.attrName = "id";
	condition5.op = EQ;
	condition5.bRhsIsAttr = 1;
	condition5.rhsAttr.relName = table2; condition5.rhsAttr.attrName = "id";
	whereExpr5->pData = (void *)(&condition5);
	whereExpr5->lc = NULL; whereExpr5->rc = NULL;

	WhereNode *whereExpr4 = new WhereNode;
	whereExpr4->type = LOGIC_OP;
	LogicOp logic_op4 = AND;
	whereExpr4->pData = (void *) (&logic_op4);
	whereExpr4->lc = whereExpr1;
	whereExpr4->rc = whereExpr5;

	qlm->Delete(table1, whereExpr1);

	cout << endl << "test select 1 table----------------------" << endl;
	/*int nSelAttrs = 2;
	RelAttr *selAttrs = new RelAttr[nSelAttrs];
	selAttrs[0].relName = table1; selAttrs[0].attrName = "id";
	selAttrs[1].relName = table1; selAttrs[1].attrName = "age";*/
	int nSelAttrs = -1;
	RelAttr *selAttrs = NULL;/**/

	int nRelations = 1;
	string *relations = new string[nRelations];
	relations[0] = table1;
	//qlm->Select(nSelAttrs, selAttrs, nRelations, relations, whereExpr1);
	//qlm->Select(nSelAttrs, selAttrs, nRelations, relations, NULL);

	cout << endl << "test select 2 table----------------------" << endl;
	int nSelAttrs2 = 3;
	RelAttr *selAttrs2 = new RelAttr[nSelAttrs2];
	selAttrs2[0].relName = table1; selAttrs2[0].attrName = "id";
	selAttrs2[1].relName = table1; selAttrs2[1].attrName = "age";
	selAttrs2[2].relName = table2; selAttrs2[2].attrName = "gender";
	/*int nSelAttrs2 = -1;
	RelAttr *selAttrs2 = NULL;*/
	int nRelations2 = 2;
	string *relations2 = new string[nRelations2];
	relations2[0] = table1;
	relations2[1] = table2;
	//qlm->Select(nSelAttrs2, selAttrs2, nRelations2, relations2, whereExpr5);
	//qlm->Select(nSelAttrs2, selAttrs2, nRelations2, relations2, NULL);

	cout << endl << "test update----------------------" << endl;

	ExcNode *excLc = new ExcNode;
	excLc->type = VALUE;
	Value value_lc;
	double upd = 40;
	value_lc.type = FLOAT; value_lc.data = (void *)(&upd);
	excLc->pData = (void *)(&value_lc);
	excLc->lc = excLc->rc = NULL;

	ExcNode * excRc = new ExcNode;
	excRc->type = RELATTR;
	RelAttr attrRc; attrRc.relName = table1; attrRc.attrName = "age";
	excRc->pData = (void *)(&attrRc);
	excRc->lc = excRc->rc = NULL;

	ExcNode *excRoot = new ExcNode;
	excRoot->type = ARITH_OP;
	ArithOp op = ADD;
	excRoot->pData = (void *)(&op);
	excRoot->lc = excLc;
	excRoot->rc = excRc;

	RelAttr updAttr; updAttr.relName = table1; updAttr.attrName = "age";
	//qlm->Update(table1, updAttr, excRoot, whereExpr1);

	//全表扫描
	cout << endl << "全表扫描 table1----------------------" << endl;
	string new_relName = currentdb + "/" + table1;
	RM_FileHandle rm_handler;
	rmm->OpenFile(new_relName.c_str(), rm_handler);
	RM_FileScan rm_scan;
	rm_scan.OpenScan(rm_handler, NONETYPE, 0, 0, 0, NO, NULL);
	RM_Record record;
	RID rid;
	while(rm_scan.GetNextRec(record, rid) == 0){
		char *rbytes = record.GetRdata();
		cout << *(long long*)(rbytes + 8) << " " << *(long long*)(rbytes + 16) << " " << *(long long*)(rbytes + 24) << " " << rbytes + 32 << endl;
		delete []rbytes;
	}
	rm_scan.CloseScan();
	rmm->CloseFile(rm_handler);

	cout << endl << "全表扫描 table2----------------------" << endl;
	new_relName = currentdb + "/" + table2;
	rmm->OpenFile(new_relName.c_str(), rm_handler);
	rm_scan.OpenScan(rm_handler, NONETYPE, 0, 0, 0, NO, NULL);
	while (rm_scan.GetNextRec(record, rid) == 0) {
		char *rbytes = record.GetRdata();
		cout << *(long long*) (rbytes + 8) << " " << *(long long*) (rbytes + 16)
				<< " " << *(long long*) (rbytes + 24) << " " << rbytes + 32
				<< endl;
		delete []rbytes;
	}
	rm_scan.CloseScan();
	rmm->CloseFile(rm_handler);

    delete []values;
    delete fm;
    delete bpm;
    delete rmm;
    delete ixm;
    delete smm;
    delete qlm;
}