BadgerDB
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends
Public Member Functions | Protected Attributes
badgerdb::RelCatalog Class Reference

The class implementing the Relation Catalogs. Inherited from the FileScan class. More...

#include <catalog.h>

Inheritance diagram for badgerdb::RelCatalog:
badgerdb::FileScan

List of all members.

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

BufMgrbufMgr

Detailed Description

The class implementing the Relation Catalogs. Inherited from the FileScan class.

Definition at line 97 of file catalog.h.


Constructor & Destructor Documentation

Constructor

Definition at line 16 of file relcat.cpp.

:FileScan(RELCATNAME, bufferMgr)
{
}

Destructor

Definition at line 168 of file relcat.cpp.

{
}

Member Function Documentation

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();
}

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.

{
  Page *dPage;
  bufMgr->readPage(file, rid.page_number, dPage);
  dPage->deleteRecord(rid);
  bufMgr->unPinPage(file, rid.page_number, true);
}
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.

{
  if (curPage != NULL)
  {
    bufMgr->unPinPage(file, (*filePageIter).page_number(), curDirtyFlag);
  }

  curPage = NULL;
  curDirtyFlag = false;
  filePageIter = file->begin();
  filter.clear();
}
void badgerdb::FileScan::flushFile ( ) [inherited]

Flush file from buffer manager and reset all parameters.

Definition at line 87 of file filescan.cpp.

{
  // generally must unpin last page of the scan
  if (curPage != NULL)
  {
    bufMgr->unPinPage(file, (*filePageIter).page_number(), curDirtyFlag);
    curPage = NULL;
    curDirtyFlag = false;
    filePageIter = file->begin();
  }

  bufMgr->flushFile(file);
}
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.

{
  // Solution Starts
  Page* page;

  bufMgr->readPage(file, rid.page_number, page);
  std::string retStr = page->getRecord(rid);
  bufMgr->unPinPage(file, rid.page_number, false);

  return retStr;
}
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.

{
  if(curPage != NULL)
  {
    bufMgr->unPinPage(file, (*filePageIter).page_number(), curDirtyFlag);
  }

  curDirtyFlag = false;
  filePageIter = file->beginAt(rid.page_number);
  bufMgr->readPage(file, rid.page_number, curPage); 
  pageRecordIter = curPage->beginAt(rid.slot_number);
}
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;
}

The documentation for this class was generated from the following files:
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends