00001
00008 #include <memory>
00009 #include <iostream>
00010 #include "buffer.h"
00011 #include "bufHashTbl.h"
00012 #include "exceptions/hash_already_present_exception.h"
00013 #include "exceptions/hash_not_found_exception.h"
00014 #include "exceptions/hash_table_exception.h"
00015
00016 namespace badgerdb {
00017
00018 int BufHashTbl::hash(const File* file, const PageId pageNo)
00019 {
00020 int tmp, value;
00021 tmp = (long)file;
00022 value = (tmp + pageNo) % HTSIZE;
00023 return value;
00024 }
00025
00026 BufHashTbl::BufHashTbl(int htSize)
00027 : HTSIZE(htSize)
00028 {
00029
00030 ht = new hashBucket* [htSize];
00031 for(int i=0; i < HTSIZE; i++)
00032 ht[i] = NULL;
00033 }
00034
00035 BufHashTbl::~BufHashTbl()
00036 {
00037 for(int i = 0; i < HTSIZE; i++) {
00038 hashBucket* tmpBuf = ht[i];
00039 while (ht[i]) {
00040 tmpBuf = ht[i];
00041 ht[i] = ht[i]->next;
00042 delete tmpBuf;
00043 }
00044 }
00045 delete [] ht;
00046 }
00047
00048 void BufHashTbl::insert(const File* file, const PageId pageNo, const FrameId frameNo)
00049 {
00050 int index = hash(file, pageNo);
00051
00052 hashBucket* tmpBuc = ht[index];
00053 while (tmpBuc) {
00054 if (tmpBuc->file == file && tmpBuc->pageNo == pageNo)
00055 throw HashAlreadyPresentException(tmpBuc->file->filename(), tmpBuc->pageNo, tmpBuc->frameNo);
00056 tmpBuc = tmpBuc->next;
00057 }
00058
00059 tmpBuc = new hashBucket;
00060 if (!tmpBuc)
00061 throw HashTableException();
00062
00063 tmpBuc->file = (File*) file;
00064 tmpBuc->pageNo = pageNo;
00065 tmpBuc->frameNo = frameNo;
00066 tmpBuc->next = ht[index];
00067 ht[index] = tmpBuc;
00068 }
00069
00070 void BufHashTbl::lookup(const File* file, const PageId pageNo, FrameId &frameNo)
00071 {
00072 int index = hash(file, pageNo);
00073 hashBucket* tmpBuc = ht[index];
00074 while (tmpBuc) {
00075 if (tmpBuc->file == file && tmpBuc->pageNo == pageNo)
00076 {
00077 frameNo = tmpBuc->frameNo;
00078 return;
00079 }
00080 tmpBuc = tmpBuc->next;
00081 }
00082
00083 throw HashNotFoundException(file->filename(), pageNo);
00084 }
00085
00086 void BufHashTbl::remove(const File* file, const PageId pageNo) {
00087
00088 int index = hash(file, pageNo);
00089 hashBucket* tmpBuc = ht[index];
00090 hashBucket* prevBuc = NULL;
00091
00092 while (tmpBuc)
00093 {
00094 if (tmpBuc->file == file && tmpBuc->pageNo == pageNo)
00095 {
00096 if(prevBuc)
00097 prevBuc->next = tmpBuc->next;
00098 else
00099 ht[index] = tmpBuc->next;
00100
00101 delete tmpBuc;
00102 return;
00103 }
00104 else
00105 {
00106 prevBuc = tmpBuc;
00107 tmpBuc = tmpBuc->next;
00108 }
00109 }
00110
00111 throw HashNotFoundException(file->filename(), pageNo);
00112 }
00113
00114 }