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 }