00001 00008 #pragma once 00009 00010 #include <fstream> 00011 #include <string> 00012 #include <map> 00013 #include <memory> 00014 00015 #include "page.h" 00016 00017 namespace wiscdb { 00018 00019 class FileIterator; 00020 00024 struct FileHeader { 00028 PageId num_pages; 00029 00033 PageId first_used_page; 00034 00038 PageId num_free_pages; 00039 00043 PageId first_free_page; 00044 00051 bool operator==(const FileHeader& rhs) const { 00052 return num_pages == rhs.num_pages && 00053 num_free_pages == rhs.num_free_pages && 00054 first_used_page == rhs.first_used_page && 00055 first_free_page == rhs.first_free_page; 00056 } 00057 }; 00058 00075 class File { 00076 public: 00077 00088 File(const std::string& name, const bool create_new); 00089 00097 static void remove(const std::string& filename); 00098 00104 static bool isOpen(const std::string& filename); 00105 00106 00112 static bool exists(const std::string& filename); 00113 00118 virtual ~File(); 00119 00125 virtual Page allocatePage(PageId &new_page_number) = 0; 00126 00135 virtual Page readPage(const PageId page_number) const = 0; 00136 00144 virtual void writePage(const PageId page_number, const Page& new_page) = 0; 00145 00151 virtual void deletePage(const PageId page_number) = 0; 00152 00158 const std::string& filename() const { return filename_; } 00159 00165 PageId getFirstPageNo(); 00166 00167 protected: 00175 static std::streampos pagePosition(const PageId page_number) { 00176 return sizeof(FileHeader) + ((page_number - 1) * Page::SIZE); 00177 } 00178 00190 void openIfNeeded(const bool create_new); 00191 00197 void close(); 00198 00204 FileHeader readHeader() const; 00205 00211 void writeHeader(const FileHeader& header); 00212 00213 typedef std::map<std::string, std::shared_ptr<std::fstream> > StreamMap; 00214 typedef std::map<std::string, int> CountMap; 00215 00219 static StreamMap open_streams_; 00220 00224 static CountMap open_counts_; 00225 00229 std::string filename_; 00230 00234 std::shared_ptr<std::fstream> stream_; 00235 00236 friend class FileIterator; 00237 }; 00238 00239 class PageFile : public File { 00240 public: 00241 00248 static PageFile create(const std::string& filename); 00249 00260 static PageFile open(const std::string& filename); 00261 00272 PageFile(const std::string& name, const bool create_new); 00273 00280 PageFile(const PageFile& other); 00281 00288 PageFile& operator=(const PageFile& rhs); 00289 00294 ~PageFile(); 00295 00301 Page allocatePage(PageId &new_page_number); 00302 00311 Page readPage(const PageId page_number) const; 00312 00320 void writePage(const PageId page_number, const Page& new_page); 00321 00327 void deletePage(const PageId page_number); 00328 00334 FileIterator begin(); 00335 00342 FileIterator end(); 00343 00344 private: 00345 00359 Page readPage(const PageId page_number, const bool allow_free) const; 00360 00370 void writePage(const PageId page_number, const PageHeader& header, 00371 const Page& new_page); 00372 00380 PageHeader readPageHeader(const PageId page_number) const; 00381 00382 friend class FileIterator; 00383 }; 00384 00385 class RawFile : public File { 00386 public: 00387 00394 static RawFile create(const std::string& filename); 00395 00406 static RawFile open(const std::string& filename); 00407 00420 RawFile(const std::string& name, const bool create_new); 00421 00428 RawFile(const RawFile& other); 00429 00436 RawFile& operator=(const RawFile& rhs); 00437 00442 ~RawFile(); 00443 00449 Page allocatePage(PageId &new_page_number); 00450 00459 Page readPage(const PageId page_number) const; 00460 00468 void writePage(const PageId page_number, const Page& new_page); 00469 00475 void deletePage(const PageId page_number); 00476 }; 00477 00478 }