BadgerDB
|
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 badgerdb { 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 00341 FileIterator beginAt(PageId pageId); 00342 00349 FileIterator end(); 00350 00351 private: 00352 00366 Page readPage(const PageId page_number, const bool allow_free) const; 00367 00377 void writePage(const PageId page_number, const PageHeader& header, 00378 const Page& new_page); 00379 00387 PageHeader readPageHeader(const PageId page_number) const; 00388 00389 friend class FileIterator; 00390 }; 00391 00392 class BlobFile : public File { 00393 public: 00394 00401 static BlobFile create(const std::string& filename); 00402 00413 static BlobFile open(const std::string& filename); 00414 00427 BlobFile(const std::string& name, const bool create_new); 00428 00435 BlobFile(const BlobFile& other); 00436 00443 BlobFile& operator=(const BlobFile& rhs); 00444 00449 ~BlobFile(); 00450 00456 Page allocatePage(PageId &new_page_number); 00457 00466 Page readPage(const PageId page_number) const; 00467 00475 void writePage(const PageId page_number, const Page& new_page); 00476 00482 void deletePage(const PageId page_number); 00483 }; 00484 00485 }