BadgerDB
/afs/cs.wisc.edu/u/n/w/nwilliam/private/workspace/Quut/src/attrcat.cpp
00001 #include "catalog.h"
00002 #include <cstdlib>
00003 #include <sstream>
00004 #include <cstring>
00005 #include "index.h"
00006 #include "exceptions/attribute_not_found_exception.h"
00007 #include "exceptions/index_not_found_exception.h"
00008 #include "exceptions/index_already_exists_exception.h"
00009 #include "exceptions/end_of_file_exception.h"
00010 #include "exceptions/bad_opcodes_exception.h"
00011 
00012 namespace badgerdb {
00013 
00014 static int attrCmp(const void* a1, const void* a2)
00015 {
00016    return ((AttrDesc*)a1)->attrOffset - ((AttrDesc*)a2)->attrOffset; 
00017 }
00018 
00019 AttrCatalog::AttrCatalog(BufMgr *bufferMgr)
00020 :FileScan(ATTRCATNAME, bufferMgr)
00021 {
00022 }
00023 
00024 void AttrCatalog::getInfo(const std::string &relation, const std::string &attrName, AttrDesc &attrdesc)
00025 {
00026   RecordId rid;
00027 
00028   startScan(0, relation.size() + 1, STRING, relation, EQ);
00029 
00030   while(1)
00031   {
00032     try
00033     {
00034       scanNext(rid);
00035       std::string recordStr = getRecord();
00036 
00037       assert(sizeof(AttrDesc) == recordStr.size());
00038 
00039       memcpy(&attrdesc, recordStr.c_str(), sizeof(AttrDesc));
00040       if(std::string(attrdesc.attrName) == attrName)
00041         break;
00042     }
00043     catch(EndOfFileException e)
00044     {
00045       throw AttributeNotFoundException();
00046     }
00047   }
00048 
00049   endScan();
00050 }
00051 
00052 
00053 void AttrCatalog::addInfo(AttrDesc &attrdesc)
00054 {
00055   RecordId outRid;
00056   std::string new_data(reinterpret_cast<char*>(&attrdesc), sizeof(AttrDesc));
00057   insertRecord(new_data, outRid);
00058 }
00059 
00060 
00061 void AttrCatalog::removeInfo(const std::string &relation, const std::string &attrName)
00062 {
00063   RecordId rid;
00064   AttrDesc attrdesc;
00065 
00066   startScan(0, relation.size() + 1, STRING, relation, EQ);
00067 
00068   while(1)
00069   {
00070     try
00071     {
00072       scanNext(rid);
00073       std::string recordStr = getRecord();
00074 
00075       assert(sizeof(AttrDesc) == recordStr.size());
00076 
00077       memcpy(&attrdesc, recordStr.c_str(), sizeof(AttrDesc));
00078       if (std::string(attrdesc.attrName) == attrName)
00079         break;
00080     }
00081     catch(EndOfFileException e)
00082     {
00083       throw AttributeNotFoundException();
00084     }
00085   }
00086 
00087   endScan();
00088 
00089   deleteRecord(rid);
00090 }
00091 
00092 void AttrCatalog::getRelInfo(const std::string &relation, int &attrCnt, AttrDesc *&attrs)
00093 {
00094   RecordId rid;
00095 
00096   startScan(0, relation.size() + 1, STRING, relation, EQ);
00097 
00098   attrCnt = 0;
00099   int curSize = 8;
00100   attrs = new AttrDesc [curSize];
00101 
00102   memset (attrs, 0, curSize*sizeof(AttrDesc)); // keep purify happy.
00103 
00104   while(1)
00105   {
00106     try
00107     {
00108       scanNext(rid);
00109       std::string recordStr = getRecord();
00110 
00111       assert(sizeof(AttrDesc) == recordStr.size());
00112 
00113       ++attrCnt;
00114 
00115       // Check if the attrs array can hold this entry.
00116       if (attrCnt > curSize)
00117       {
00118         // reallocate the attrs array and start over.
00119         AttrDesc* newArray = new AttrDesc [curSize*2]; // double the size of the array.
00120         memset (newArray, 0, curSize*2*sizeof(AttrDesc)); // keep purify happy.
00121         memcpy (newArray, attrs, curSize*sizeof(AttrDesc)); // copy the old contents
00122         delete [] attrs;  // free up the previously allocated memory.
00123         attrs = newArray; // point to the new (larger) array.
00124         curSize *= 2;
00125       }
00126 
00127       memcpy(&attrs[attrCnt - 1], recordStr.c_str(), sizeof(AttrDesc));
00128     }
00129     catch(EndOfFileException e)
00130     {
00131       break;
00132     }
00133   }
00134 
00135   endScan();
00136 
00137   qsort(attrs, attrCnt, sizeof(AttrDesc), badgerdb::attrCmp);
00138 }
00139 
00140 //
00141 // Drops a relation. It performs the following steps:
00142 //
00143 //      destroys any index files
00144 //  removes the catalog entries for the relation
00145 //
00146 // Returns:
00147 //  OK on success
00148 //  error code otherwise
00149 //
00150 
00151 void AttrCatalog::dropRelation(const std::string &relation)
00152 {
00153   AttrDesc *attrs;
00154   int attrCnt, i;
00155 
00156   // get attribute information
00157 
00158   getRelInfo(relation, attrCnt, attrs);
00159 
00160   // first drop any index files
00161   // (this must occur before removeInfo() is called because
00162   // dropIndex computes offsets (needed in index filenames)
00163   // based on attrcat entries!)
00164 
00165   for(i = 0; i < attrCnt; i++)
00166   {
00167     if(attrs[i].indexed)
00168     {
00169       dropIndex(relation, attrs[i].attrName);
00170     }
00171   }
00172 
00173   // remove entries from catalog
00174   for(i = 0; i < attrCnt; i++)
00175   {
00176     removeInfo(relation, attrs[i].attrName);
00177   }
00178 
00179   delete [] attrs;
00180 }
00181 
00182 AttrCatalog::~AttrCatalog()
00183 {
00184 }
00185 
00186 //
00187 // Creates an index on attribute `attrName' of relation `relation.'
00188 // It performs the following steps:
00189 //
00190 //      creates the appropriate index file by instantiating an Index object, which
00191 //      creates the index file.
00192 //  marks the attribute `indexed' in attrcat
00193 //
00194 // Returns:
00195 //  OK on success
00196 //  error code otherwise
00197 //
00198 
00199 void AttrCatalog::addIndex(const std::string &relation, const std::string &attrName)
00200 {
00201   AttrDesc ad;
00202 
00203   // get attribute information
00204   getInfo(relation, attrName, ad);
00205 
00206   if(ad.indexed)
00207     throw IndexAlreadyExistsException();
00208 
00209   // create index file
00210   Index index(relation, ad.attrOffset, ad.attrLen, (Datatype)ad.attrType, 1, bufMgr);
00211   //index.printBucs();
00212 
00213   // modify entry in attrcat
00214   ad.indexed = true;
00215 
00216   removeInfo(relation, attrName);
00217   addInfo(ad);
00218 }
00219 
00220 
00221 
00222 void AttrCatalog::dropIndex(const std::string &relation, const std::string &attrName)
00223 {
00224   AttrDesc ad;
00225 
00226   // get attribute information
00227   getInfo(relation, attrName, ad);
00228 
00229   if(ad.indexed == false)
00230     throw IndexNotFoundException();
00231 
00232   // destroy file
00233   std::ostringstream outputString;
00234   outputString << relation << '.' << ad.attrOffset << std::endl;
00235   std::string tmpString = outputString.str();
00236 
00237   File::remove(tmpString);
00238 
00239   // modify entry in attrcat
00240   ad.indexed = false;
00241 
00242   removeInfo(relation, attrName);
00243   addInfo(ad);
00244 }
00245 
00246 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends