//Insert the exact field of each record into the indexing t_rc SSQLM_Manager::InsertIndexEntries(REM_RecordFileHandle &rfh, int attrOffset/*, INXM_IndexHandle ih*/) { t_rc rc; int numReservedPages = rfh.sfh.GetNumReservedPages(); int numberofSlots = rfh.rfsh.nrecords; REM_RecordID rid; REM_RecordHandle rh; int slot = 0; int pageID = 2; char *data; if(numReservedPages < 2) return SSQLM_NOENTRYTOINDEX; if(numberofSlots == 0) return SSQLM_NOENTRYTOINDEX; for( ; pageID <= numReservedPages; pageID++) { for( ; slot <= rfh.rfsh.recordsPerPage; slot++) { if(slot >(rfh.rfsh.nrecords - 1)) return OK; rc = rid.SetPageID(pageID); if(rc != OK) return rc; rc = rid.SetSlot(slot); if(rc != OK) return rc; rc = rfh.ReadRecord(rid, rh); if(rc != OK) return rc; rc = rh.GetData(data); if(rc != OK) return rc; /*rc = ih.InsertEntry(data[attrOffset], rid); if(rc != OK) return rc; */ } } }
t_rc SSQLM_Manager::CompareAttributes(t_attrInfo comparisonAttribute, t_attrInfo convertionAttribute, t_compOp compOp, vector<char *> &pData) { t_rc rc; REM_RecordFileHandle rfhCompare; REM_RecordFileHandle rfhConvertion; REM_RecordHandle rhCompare; REM_RecordHandle rhConvertion; REM_RecordID ridCompare; REM_RecordID ridConvertion; if(comparisonAttribute.indexNo != -1) { /*INXM_IndexHandle indesHandle; INXM_IndexScan indexScan; std::stringstream ss; ss << comparisonAttribute.relName << "." << comparisonAttribute.indexNo; rc = inxm.OpenIndex(ss.str(), comparisonAttribute.indexNo, indexHandle); if(rc != OK) return rc; rc = indexScan.OpenIndexScan(indexHandle, compOp, */ }else { if(comparisonAttribute.relName != convertionAttribute.relName) { rc = rfm.OpenRecordFile(comparisonAttribute.relName, rfhCompare); if(rc != OK) return rc; rc = rfm.OpenRecordFile(convertionAttribute.relName, rfhConvertion); if(rc != OK) return rc; REM_RecordFileScan fileScan; int slotCompare = 0; int pageIDCompare = 2; int slotConvertion = 0; int pageIDConvertion = 2; for( ;pageIDCompare <= rfhCompare.sfh.GetNumReservedPages(); pageIDCompare++) { for( ;slotCompare <= rfhCompare.rfsh.nrecords; slotCompare++) { rc = ridCompare.SetPageID(pageIDCompare); if(rc != OK) return rc; rc = ridCompare.SetSlot(slotCompare); if(rc != OK) return rc; rc = rfhCompare.ReadRecord(ridCompare, rhCompare); if(rc != OK) return rc; char *dataCompare; rc = rhCompare.GetData(dataCompare); if(rc != OK) return rc; rc = fileScan.OpenRecordScan(rfhConvertion, convertionAttribute.attrType, convertionAttribute.attrLength, convertionAttribute.offset, compOp, dataCompare); if(rc != OK) return rc; char *dataConvertion; while(fileScan.GetNextRecord(rhConvertion) == OK){ rc = rhConvertion.GetData(dataConvertion); if(rc != OK) return rc; pData.push_back(dataCompare); pData.push_back(dataConvertion); } fileScan.CloseRecordScan(); } } } } return OK; }
t_rc REM_RecordFileHandle::InsertRecord(const char *pData, REM_RecordID &rid) { // If file is open. if (!this->is_open) { return REM_FHCLOSED; } t_rc rc; // Find an empty page to write the new record. STORM_PageHandle target_page; REM_PageHeader page_header = {0}; // We store 0 ,we haven't any record yet. char *page_data; //If there is no free space on this page we reserve a new page. if (this->rem_file_header.is_last_page_full) { rc = sfh.ReservePage(target_page); // Reserve the new page. if (rc != OK) { return rc; } // We mark the last page as not full. this->rem_file_header.is_last_page_full = false; // Update file header and mark it as dirty. memcpy(this->pData_fileHeader, &this->rem_file_header, REM_FILEHEADER_SIZE); rc = this->sfh.MarkPageDirty(this->page_num_file_header); if (rc != OK) { return rc; } // Get a pointer to the data of the new page to write data. rc = target_page.GetDataPtr(&page_data); if (rc != OK) { return rc; } } // If we have free space in a page, we just get the page. else { rc = this->sfh.GetLastPage(target_page); if (rc != OK) { return rc; } // Get a pointer to the data of the the page to read the REM Page Header. rc = target_page.GetDataPtr(&page_data); if (rc != OK) { return rc; } memcpy(&page_header, page_data, REM_PAGEHEADER_SIZE); } //We calculate the corect offset(page header size + the offset) of each record there and we place the data memcpy(&page_data[REM_PAGEHEADER_SIZE+(page_header.n_records*this->rem_file_header.record_size)], pData, this->rem_file_header.record_size); page_header.n_records+=1; this->rem_file_header.n_records+=1; memcpy(this->pData_fileHeader, &this->rem_file_header, REM_FILEHEADER_SIZE); rc = this->sfh.MarkPageDirty(this->page_num_file_header); if (rc != OK) { return rc; } // Increase the number of records in the page header. This number is also the slot number of the record. int slot_num = page_header.n_records; // Declare page number we are currently working on. int page_num; rc = target_page.GetPageID(page_num); if (rc != OK) { return rc; } //If page is full. if (page_header.n_records == this->rem_file_header.records_per_page) { this->rem_file_header.is_last_page_full = true; // Update the file header and mark as dirty. memcpy(this->pData_fileHeader, &this->rem_file_header, REM_FILEHEADER_SIZE); rc = this->sfh.MarkPageDirty(this->page_num_file_header); if (rc != OK) { return rc; } // Get a pointer to the data of the new page to write the new data. rc = target_page.GetDataPtr(&page_data); if (rc != OK) { return rc; } } // Write the new REM Page Header. memcpy(page_data, &page_header, REM_PAGEHEADER_SIZE); // Mark the page as dirty because we modified it rc = this->sfh.MarkPageDirty(page_num); if (rc != OK) { return rc; } this->sfh.FlushPage(page_num); // We are flushing pages // Unpin the page rc = this->sfh.UnpinPage (page_num); if (rc != OK) { return rc; } // Set the passed RID's page and slot number rc = rid.SetPageID(page_num); if (rc != OK) { return rc; } rc = rid.SetSlot(slot_num); if (rc != OK) { return rc; } return (OK); }
t_rc REM_RecordFileHandle::InsertRecord(const char *pData, REM_RecordID &rid) { //Edit if(!open) return REM_HANDLE_IS_CLOSED; int numReservedPages=fh.GetNumReservedPages(); //πλήθος των reserved pages int i; this->pData=pData; //δεδομένα που θα βάλουμε στην εγγραφή. int pageID = 0; //ID της σελίδας όπου θα βάλουμε δεδομένα. char *pageData; //δεδομένα της σελίδας όπου θα βάλουμε την εγγραφή. for(i=0; i<numReservedPages; i++) { rc= fh.GetNextPage(pageID,ph); if(rc!=OK) return rc; rc = ph.GetPageID(pageID); if(rc!=OK) return rc; if(headerPage.bitmap.test(pageID) == false) { //if(headerPage.bitmap[pageID] == false) break; } else { rc = fh.UnpinPage(pageID); if(rc!=OK) return rc; } } //βρήκαμε σε ποια σελίδα θα μπεί η εγγραφή. if(i==numReservedPages) //πρέπει να κάνουμε νέο page reserve. { if(i == 101) return REM_PAGES_ARE_FULL; rc = fh.ReservePage(ph); if(rc!=OK) return rc; rc = ph.GetPageID(pageID); if(rc!=OK) return rc; rc = ph.GetDataPtr(&pageData); if(rc!=OK) return rc; //κάνουμε αρχικοποίηση το record header rh.recordHeader.reservedRecords=0; for(int i=0; i<headerPage.recordsPerPage; i++) //rh.recordHeader.bitmap[i] = false; rh.recordHeader.bitmap.set(i,0); } else { //δεν κάνουμε reserve νεo page, υπάρχει ήδη, διαβάζουμε το record header. rc = fh.GetPage(pageID,ph); if(rc!=OK) return rc; rc = ph.GetDataPtr(&pageData); if(rc!=OK) return rc; memcpy(&rh.recordHeader, pageData, sizeof(REM_RecordHandle::RecordHeader)); } //mexri tora vrikame pageID. Πάμε να βρούμε το slot όπου θα μπούν τα δεδομένα. int slot = -1; for(i=0; i<headerPage.recordsPerPage; i++) { //10: bitmap size //if(rh.recordHeader.bitmap[i] == false) if(rh.recordHeader.bitmap.test(i) == false) { slot = i; break; } } //βρήκαμε page και slot όπου θα βάλουμε τα δεδομένα. //ενημέρωση του record handle για την εγγραφή όπου θα μπούν τα δεδομένα. rh.Initialize(ph, slot, this->headerPage.recordSize); //εγγραφή των δεδομένων στο record. UpdateRecord(rh); //ενημέρωση του recordHeader rh.recordHeader.reservedRecords++; rh.recordHeader.bitmap.set(slot,1); //rh.recordHeader.bitmap[slot] = true; //εγγραφή του recordHeader στη σελίδα. memcpy(pageData, &rh.recordHeader,sizeof(REM_RecordHandle::RecordHeader)); //ενημέρωση της σελίδας με τις αλλαγές. rc = fh.MarkPageDirty(pageID); if(rc!=OK) return rc; rc = fh.UnpinPage(pageID); if(rc!=OK) return rc; //ενημέρωση του page header εάν χρειάζεται if(rh.recordHeader.reservedRecords == headerPage.recordsPerPage) { //είναι full η σελίδα.. rc = updatePageHeader(pageID, true); if(rc!=OK) return rc; } //ενημέρωση του record id rid.SetPageID(pageID); rid.SetSlot(slot); return OK; }
t_rc REM_RecordFileHandle::InsertRecord(const char *pData, REM_RecordID &rid) { /* Check is file is open. */ if (!this->isOpen) { return REM_FHCLOSED; } t_rc rc; /* Find an empty page to write the new record. */ STORM_PageHandle targetPage; REM_PageHeader pageHeader = {0}; // The default number of records in a page is 0. char *pageData; /* If there is no free space (lastPageID=-1) then we reserve a new page. */ if (this->remFileHeader.isLastPageFull) { rc = sfh.ReservePage(targetPage); // Reserve the new page. if (rc != OK) { return rc; } /* We mark the last page as not full. */ this->remFileHeader.isLastPageFull = false; /* We update the file header and mark as dirty. */ memcpy(this->pData_FileHeader, &this->remFileHeader, REM_FILEHEADER_SIZE); rc = this->sfh.MarkPageDirty(this->pageNum_FileHeader); if (rc != OK) { return rc; } /* Get a pointer to the data of the new page to write the new data. */ rc = targetPage.GetDataPtr(&pageData); if (rc != OK) { return rc; } } /* If we have free space in a page, we just get the page. */ else { rc = this->sfh.GetLastPage(targetPage); if (rc != OK) { return rc; } /* Get a pointer to the data of the the page to read the REM Page Header. */ rc = targetPage.GetDataPtr(&pageData); if (rc != OK) { return rc; } memcpy(&pageHeader, pageData, REM_PAGEHEADER_SIZE); } /* We write the data to the proper position. The new record offset must be the page header size + the offset of each record there * is inside the page. We always place the new record at the end of the page. */ memcpy(&pageData[REM_PAGEHEADER_SIZE+(pageHeader.nRecords*this->remFileHeader.recordSize)], pData, this->remFileHeader.recordSize); /* Increase the number of records in the page header. This number is also the slot number of the record. */ int slotNum = ++pageHeader.nRecords; /* Declare page number, which is the pageID we are currently working on. */ int pageNum; rc = targetPage.GetPageID(pageNum); if (rc != OK) { return rc; } /* Check if page is full. */ if (pageHeader.nRecords == this->remFileHeader.recordsPerPage) { this->remFileHeader.isLastPageFull = true; /* We update the file header and mark as dirty. */ memcpy(this->pData_FileHeader, &this->remFileHeader, REM_FILEHEADER_SIZE); rc = this->sfh.MarkPageDirty(this->pageNum_FileHeader); if (rc != OK) { return rc; } /* Get a pointer to the data of the new page to write the new data. */ rc = targetPage.GetDataPtr(&pageData); if (rc != OK) { return rc; } } /* Write the new REM Page Header. */ memcpy(pageData, &pageHeader, REM_PAGEHEADER_SIZE); /* Mark the page as dirty because we modified it */ rc = this->sfh.MarkPageDirty(pageNum); if (rc != OK) { return rc; } this->sfh.FlushPage(pageNum); // We should reconsider when we are flushing pages!!! /* Unpin the page */ rc = this->sfh.UnpinPage (pageNum); if (rc != OK) { return rc; } /* Set the passed RID's page number and slot number */ rc = rid.SetPageID(pageNum); if (rc != OK) { return rc; } rc = rid.SetSlot(slotNum); if (rc != OK) { return rc; } /* Successfuly inserted record */ return (OK); }