00001 00006 #pragma once 00007 00008 #include <fstream> 00009 #include <string> 00010 #include <map> 00011 #include <memory> 00012 00013 #include "page.h" 00014 00015 namespace wiscdb { 00016 00017 class FileIterator; 00018 00022 struct FileHeader { 00026 PageId num_pages; 00027 00031 PageId first_used_page; 00032 00036 PageId num_free_pages; 00037 00041 PageId first_free_page; 00042 00049 bool operator==(const FileHeader& rhs) const { 00050 return num_pages == rhs.num_pages && 00051 num_free_pages == rhs.num_free_pages && 00052 first_used_page == rhs.first_used_page && 00053 first_free_page == rhs.first_free_page; 00054 } 00055 }; 00056 00071 class File { 00072 public: 00079 static File create(const std::string& filename); 00080 00094 static File open(const std::string& filename); 00095 00103 static void remove(const std::string& filename); 00104 00110 static bool isOpen(const std::string& filename); 00111 00112 00118 static bool exists(const std::string& filename); 00119 00126 File(const File& other); 00127 00134 File& operator=(const File& rhs); 00135 00140 ~File(); 00141 00147 Page allocatePage(); 00148 00157 Page readPage(const PageId page_number) const; 00158 00166 void writePage(const Page& new_page); 00167 00173 void deletePage(const PageId page_number); 00174 00180 const std::string& filename() const { return filename_; } 00181 00187 FileIterator begin(); 00188 00195 FileIterator end(); 00196 00202 void close(); 00203 00204 private: 00212 static std::streampos pagePosition(const PageId page_number) { 00213 return sizeof(FileHeader) + ((page_number - 1) * Page::SIZE); 00214 } 00215 00230 File(const std::string& name, const bool create_new); 00231 00243 void openIfNeeded(const bool create_new); 00244 00258 Page readPage(const PageId page_number, const bool allow_free) const; 00259 00268 void writePage(const PageId page_number, const Page& new_page); 00269 00279 void writePage(const PageId page_number, const PageHeader& header, 00280 const Page& new_page); 00281 00287 FileHeader readHeader() const; 00288 00294 void writeHeader(const FileHeader& header); 00295 00303 PageHeader readPageHeader(const PageId page_number) const; 00304 00305 typedef std::map<std::string, 00306 std::shared_ptr<std::fstream> > StreamMap; 00307 typedef std::map<std::string, int> CountMap; 00308 00312 static StreamMap open_streams_; 00313 00317 static CountMap open_counts_; 00318 00322 std::string filename_; 00323 00327 std::shared_ptr<std::fstream> stream_; 00328 00329 friend class FileIterator; 00330 friend class FileTest; 00331 }; 00332 00333 }