The class implementing the Relation Catalogs. Inherited from the FileScan class. More...
#include <catalog.h>
Public Member Functions | |
RelCatalog (BufMgr *bufferMgr) | |
void | getInfo (const std::string &relation, RelDesc &reldesc) |
void | addInfo (RelDesc &reldesc) |
void | removeInfo (const std::string &relation) |
void | createRel (const std::string &relation, int attrCnt, const attrInfo attrList[]) |
void | destroyRel (const std::string &relation) |
void | addIndex (const std::string &relation, const std::string &attrName) |
void | dropIndex (const std::string &relation, const std::string &attrName) |
void | help (const std::string &rName) |
~RelCatalog () | |
void | insertRecord (const std::string &rec, RecordId &outRid) |
void | deleteRecord (RecordId rid) |
void | startScan (int offset, int length, Datatype type, std::string filter, Operator op) |
void | endScan () |
void | scanNext (RecordId &outRid) |
std::string | getRecord () |
std::string | getRandomRecord (RecordId rid) |
void | gotoMark (RecordId rid) |
bool | matchRec (const std::string &rec) |
void | flushFile () |
void | markDirty () |
Protected Attributes | |
BufMgr * | bufMgr |
The class implementing the Relation Catalogs. Inherited from the FileScan class.
badgerdb::RelCatalog::RelCatalog | ( | BufMgr * | bufferMgr | ) |
void badgerdb::RelCatalog::addIndex | ( | const std::string & | relation, |
const std::string & | attrName | ||
) |
Add index for a relation
Definition at line 242 of file relcat.cpp.
{ RelDesc rd; // get existing relation data getInfo(relation, rd); // create index file attrCat->addIndex(relation, attrName); // modify indexCnt in relcat rd.indexCnt++; removeInfo(relation); addInfo(rd); //so that select on these relations show updated information attrCat->flushFile(); this->flushFile(); }
void badgerdb::RelCatalog::addInfo | ( | RelDesc & | reldesc | ) |
Add relation to catalog.
Definition at line 45 of file relcat.cpp.
{ RecordId outRid; std::string new_data(reinterpret_cast<char*>(&reldesc), sizeof(RelDesc)); insertRecord(new_data, outRid); }
void badgerdb::RelCatalog::createRel | ( | const std::string & | relation, |
int | attrCnt, | ||
const attrInfo | attrList[] | ||
) |
Create a new relation
Definition at line 72 of file relcat.cpp.
{ RelDesc rd; AttrDesc ad; if(relation.size() >= sizeof(rd.relName)) throw BadParamException(); // make sure the relation doesn't already exist try { getInfo(relation, rd); throw RelationAlreadyExistsException(); } catch(RelationNotFoundException &e) { } //make sure there are no duplicate attribute names if(attrCnt > 1) { for(int i = 1; i < attrCnt; i++) { for(int j = 0; j < i; j++) { if(strcmp(attrList[i].attrName, attrList[j].attrName) == 0) throw DuplicateAttributeException(); } } } strcpy(rd.relName, relation.c_str()); rd.attrCnt = attrCnt; rd.indexCnt = 0; addInfo(rd); strcpy(ad.relName, relation.c_str()); int offset = 0; for(int i = 0; i < attrCnt; i++) { if (strlen(attrList[i].attrName) >= sizeof(ad.attrName)) throw BadParamException(); //TODO::remove the following offset computation, get it from the user strcpy(ad.attrName, attrList[i].attrName); ad.attrOffset = offset; ad.attrType = attrList[i].attrType; ad.attrLen = attrList[i].attrLen; ad.indexed = false; attrCat->addInfo(ad); offset += ad.attrLen; } //create relation file PageFile relFile(relation, true); //so that select on these relations show updated information attrCat->flushFile(); this->flushFile(); }
void badgerdb::FileScan::deleteRecord | ( | RecordId | rid | ) | [inherited] |
Delete a record. No need to mark the page dirty by calling markDirty().
Definition at line 79 of file filescan.cpp.
void badgerdb::RelCatalog::destroyRel | ( | const std::string & | relation | ) |
Destroy a relation
Definition at line 149 of file relcat.cpp.
{ if (relation.empty() || relation == RELCATNAME || relation == ATTRCATNAME) throw BadParamException(); // delete attrcat entries attrCat->dropRelation(relation); // delete entry from relcat removeInfo(relation); File::remove(relation); //so that select on these relations show updated information attrCat->flushFile(); this->flushFile(); }
void badgerdb::RelCatalog::dropIndex | ( | const std::string & | relation, |
const std::string & | attrName | ||
) |
Drop index from a relation.
Definition at line 271 of file relcat.cpp.
{ RelDesc rd; // get existing relation data getInfo(relation, rd); // destroy index file attrCat->dropIndex(relation, attrName); // modify indexCnt in relcat rd.indexCnt--; removeInfo(relation); addInfo(rd); //so that select on these relations show updated information attrCat->flushFile(); this->flushFile(); }
void badgerdb::FileScan::endScan | ( | ) | [inherited] |
Reset scan parameters.
Definition at line 126 of file filescan.cpp.
void badgerdb::FileScan::flushFile | ( | ) | [inherited] |
Flush file from buffer manager and reset all parameters.
Definition at line 87 of file filescan.cpp.
void badgerdb::RelCatalog::getInfo | ( | const std::string & | relation, |
RelDesc & | reldesc | ||
) |
Get relation descriptor for a relation
Definition at line 21 of file relcat.cpp.
{ RecordId rid; startScan(0, relation.size() + 1, STRING, relation, EQ); try { scanNext(rid); } catch(EndOfFileException e) { throw RelationNotFoundException(); } std::string recordStr = getRecord(); assert(sizeof(RelDesc) == recordStr.size()); memcpy(&reldesc, recordStr.c_str(), sizeof(RelDesc)); endScan(); }
std::string badgerdb::FileScan::getRandomRecord | ( | RecordId | rid | ) | [inherited] |
Read a record with RecordId rid from file.
Definition at line 226 of file filescan.cpp.
std::string badgerdb::FileScan::getRecord | ( | ) | [inherited] |
Read current record, whose RecordId was returned by last call to scanNext().
Definition at line 221 of file filescan.cpp.
{
return *pageRecordIter;
}
void badgerdb::FileScan::gotoMark | ( | RecordId | rid | ) | [inherited] |
Point to particular record in the file so that next calls to scanNext() scan file beyond this particular record.
Definition at line 35 of file filescan.cpp.
void badgerdb::RelCatalog::help | ( | const std::string & | rName | ) |
Print catalog information
Definition at line 186 of file relcat.cpp.
{ if(relation.empty()) { Utilities::Print(std::string(RELCATNAME)); return; } RelDesc rd; AttrDesc *attrs; int attrCnt; // get relation data try { getInfo(relation, rd); } catch(RelationNotFoundException &e) { return; } // get attribute data attrCat->getRelInfo(relation, attrCnt, attrs); // print relation information std::cout << "Relation name: " << rd.relName << " (" << rd.attrCnt << " attributes, " << rd.indexCnt << " indexed)" << std::endl << std::endl; printf("%16.16s Off T Len I\n\n", "Attribute name"); for(int i = 0; i < attrCnt; i++) { Datatype t = (Datatype)attrs[i].attrType; printf("%16.16s %3d %c %3d %c\n", attrs[i].attrName, attrs[i].attrOffset, (t == INTEGER ? 'i' : (t == DOUBLE ? 'f' : 's')), attrs[i].attrLen, (attrs[i].indexed ? 'Y' : 'N')); } delete [] attrs; }
void badgerdb::FileScan::insertRecord | ( | const std::string & | rec, |
RecordId & | outRid | ||
) | [inherited] |
Insert a new record in file, RecordId of inserted record returned in outRid. No need to mark the page dirty by calling markDirty().
Definition at line 48 of file filescan.cpp.
{ Page *iPage; PageId iPageNo; for (FileIterator iter = file->begin(); iter != file->end(); ++iter) { iPageNo = iter.getCurrentPageNo(); if(iPageNo == Page::INVALID_NUMBER) break; bufMgr->readPage(file, iPageNo, iPage); try { outRid = iPage->insertRecord(rec); bufMgr->unPinPage(file, iPageNo, true); return; } catch(InsufficientSpaceException &e) { bufMgr->unPinPage(file, iPageNo, false); } } bufMgr->allocPage(file, iPageNo, iPage); outRid = iPage->insertRecord(rec); bufMgr->unPinPage(file, iPageNo, true); }
void badgerdb::FileScan::markDirty | ( | ) | [inherited] |
Mark current page being scanned in FileScan dirty.
Definition at line 287 of file filescan.cpp.
{
curDirtyFlag = true;
}
bool badgerdb::FileScan::matchRec | ( | const std::string & | rec | ) | [inherited] |
Check if a record satisfies the scan parameters.
Definition at line 238 of file filescan.cpp.
{ // no filtering requested if (filter.empty()) return true; // see if offset + length is beyond end of record // maybe this should be an error??? if ((offset + length -1 ) >= rec.size()) return false; double diff = 0; // < 0 if attr < fltr switch(type) { case INTEGER: int iattr, ifltr; // word-alignment problem possible memcpy(&iattr, rec.c_str() + offset, length); memcpy(&ifltr, filter.c_str(), length); //ifltr = atoi(filter.c_str()); diff = iattr - ifltr; break; case DOUBLE: double fattr, ffltr; // word-alignment problem possible memcpy(&fattr, rec.c_str() + offset, length); memcpy(&ffltr, filter.c_str(), length); //ffltr = atof(filter.c_str()); diff = fattr - ffltr; break; case STRING: diff = strncmp(rec.c_str() + offset, filter.c_str(), length); break; } switch(op) { case LT: if (diff < 0.0) return true; break; case LTE: if (diff <= 0.0) return true; break; case EQ: if (diff == 0.0) return true; break; case GTE: if (diff >= 0.0) return true; break; case GT: if (diff > 0.0) return true; break; case NE: if (diff != 0.0) return true; break; default: break; } return false; }
void badgerdb::RelCatalog::removeInfo | ( | const std::string & | relation | ) |
Remove a relation from catalog
Definition at line 52 of file relcat.cpp.
{ RecordId rid; startScan(0, relation.size() + 1, STRING, relation, EQ); try { scanNext(rid); } catch(EndOfFileException e) { throw RelationNotFoundException(); } endScan(); deleteRecord(rid); }
void badgerdb::FileScan::scanNext | ( | RecordId & | outRid | ) | [inherited] |
Returns RecordId of next record that satisfies the scan parameters, if any.
Definition at line 139 of file filescan.cpp.
{ std::string rec; if(filePageIter == file->end()) { throw EndOfFileException(); } // special case of the first record of the first page of the file if (curPage == NULL) { // need to get the first page of the file filePageIter = file->begin(); if(filePageIter == file->end()) { throw EndOfFileException(); } // read the first page of the file bufMgr->readPage(file, (*filePageIter).page_number(), curPage); curDirtyFlag = false; // get the first record off the page pageRecordIter = curPage->begin(); if(pageRecordIter != curPage->end()) { // get pointer to record rec = *pageRecordIter; if(matchRec(rec)) { outRid = pageRecordIter.getCurrentRecord(); return; } } } // Loop, looking for a record that satisfied the predicate. // First try and get the next record off the current page pageRecordIter++; while(1) { while (pageRecordIter == curPage->end()) { // unpin the current page bufMgr->unPinPage(file, (*filePageIter).page_number(), curDirtyFlag); curPage = NULL; curDirtyFlag = false; filePageIter++; if (filePageIter == file->end()) { curPage = NULL; throw EndOfFileException(); } // read the next page of the file bufMgr->readPage(file, (*filePageIter).page_number(), curPage); // get the first record off the page pageRecordIter = curPage->begin(); } while (pageRecordIter != curPage->end()) { rec = *pageRecordIter; if(matchRec(rec)) { // return rid of the record outRid = pageRecordIter.getCurrentRecord(); return; } pageRecordIter++; } } }
void badgerdb::FileScan::startScan | ( | int | offset, |
int | length, | ||
Datatype | type, | ||
std::string | filter, | ||
Operator | op | ||
) | [inherited] |
To set up scan parameters used by scanNext. If just want to scan all the records in the file, no need to call this, you may directly call scanNext().
Definition at line 108 of file filescan.cpp.
{ curPage = NULL; curDirtyFlag = false; filePageIter = file->begin(); if (filterIn.empty()) { // no filtering requested filter.clear(); return; } offset = offsetIn; length = lengthIn; type = typeIn; filter = filterIn; op = opIn; }