BadgerDB
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends Pages
Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes | Friends | List of all members
badgerdb::PageFile Class Reference
Inheritance diagram for badgerdb::PageFile:
badgerdb::File

Public Member Functions

 PageFile (const std::string &name, const bool create_new)
 
 PageFile (const PageFile &other)
 
PageFileoperator= (const PageFile &rhs)
 
 ~PageFile ()
 
Page allocatePage (PageId &new_page_number)
 
Page readPage (const PageId page_number) const
 
void writePage (const PageId page_number, const Page &new_page)
 
void deletePage (const PageId page_number)
 
FileIterator begin ()
 
FileIterator end ()
 
const std::string & filename () const
 
PageId getFirstPageNo ()
 

Static Public Member Functions

static PageFile create (const std::string &filename)
 
static PageFile open (const std::string &filename)
 
static void remove (const std::string &filename)
 
static bool isOpen (const std::string &filename)
 
static bool exists (const std::string &filename)
 

Protected Types

typedef std::map< std::string,
std::shared_ptr< std::fstream > > 
StreamMap
 
typedef std::map< std::string,
int > 
CountMap
 

Protected Member Functions

void openIfNeeded (const bool create_new)
 
void close ()
 
FileHeader readHeader () const
 
void writeHeader (const FileHeader &header)
 

Static Protected Member Functions

static std::streampos pagePosition (const PageId page_number)
 

Protected Attributes

std::string filename_
 
std::shared_ptr< std::fstream > stream_
 

Static Protected Attributes

static StreamMap open_streams_
 
static CountMap open_counts_
 

Friends

class FileIterator
 

Detailed Description

Definition at line 239 of file file.h.

Constructor & Destructor Documentation

badgerdb::PageFile::PageFile ( const std::string &  name,
const bool  create_new 
)

Constructs a file object representing a file on the filesystem.

Parameters
nameName of file.
create_newWhether to create a new file.
Exceptions
FileExistsExceptionIf the underlying file exists and create_new is true.
FileNotFoundExceptionIf the underlying file doesn't exist and create_new is false.

Definition at line 143 of file file.cpp.

144 : File(name, create_new)
145 {
146 }
File(const std::string &name, const bool create_new)
Definition: file.cpp:67
badgerdb::PageFile::PageFile ( const PageFile other)

Copy constructor.

Parameters
otherFile object to copy.
Returns
A copy of the File object.

Definition at line 151 of file file.cpp.

152 : File(other.filename_, false /* create_new */)
153 {
154 }
File(const std::string &name, const bool create_new)
Definition: file.cpp:67
badgerdb::PageFile::~PageFile ( )

Destructor that automatically closes the underlying file if no other File objects are using it.

Definition at line 148 of file file.cpp.

148  {
149 }

Member Function Documentation

Page badgerdb::PageFile::allocatePage ( PageId new_page_number)
virtual

Allocates a new page in the file.

Returns
The new page.

Implements badgerdb::File.

Definition at line 165 of file file.cpp.

165  {
166  FileHeader header = readHeader();
167  Page new_page;
168  Page existing_page;
169  if (header.num_free_pages > 0) {
170  new_page = readPage(header.first_free_page, true /* allow_free */);
171  new_page.set_page_number(header.first_free_page);
172  new_page_number = new_page.page_number();
173  header.first_free_page = new_page.next_page_number();
174  --header.num_free_pages;
175 
176  if (header.first_used_page == Page::INVALID_NUMBER ||
177  header.first_used_page > new_page.page_number()) {
178  // Either have no pages used or the head of the used list is a page later
179  // than the one we just allocated, so add the new page to the head.
180  if (header.first_used_page > new_page.page_number()) {
181  new_page.set_next_page_number(header.first_used_page);
182  }
183  header.first_used_page = new_page.page_number();
184  } else {
185  // New page is reused from somewhere after the beginning, so we need to
186  // find where in the used list to insert it.
187  PageId next_page_number = Page::INVALID_NUMBER;
188  for (FileIterator iter = begin(); iter != end(); ++iter) {
189  next_page_number = (*iter).next_page_number();
190  if (next_page_number > new_page.page_number() ||
191  next_page_number == Page::INVALID_NUMBER) {
192  existing_page = *iter;
193  break;
194  }
195  }
196  existing_page.set_next_page_number(new_page.page_number());
197  new_page.set_next_page_number(next_page_number);
198  }
199 
200  assert((header.num_free_pages == 0) ==
201  (header.first_free_page == Page::INVALID_NUMBER));
202  }
203  else
204  {
205  new_page.set_page_number(header.num_pages);
206  new_page_number = new_page.page_number();
207 
208  if (header.first_used_page == Page::INVALID_NUMBER)
209  {
210  header.first_used_page = new_page.page_number();
211  }
212  else
213  {
214  // If we have pages allocated, we need to add the new page to the tail
215  // of the linked list.
216  for (FileIterator iter = begin(); iter != end(); ++iter) {
217  if ((*iter).next_page_number() == Page::INVALID_NUMBER) {
218  existing_page = *iter;
219  break;
220  }
221  }
222  assert(existing_page.isUsed());
223  existing_page.set_next_page_number(new_page.page_number());
224  }
225  ++header.num_pages;
226  }
227  writePage(new_page_number, new_page.header_, new_page);
228  if (existing_page.page_number() != Page::INVALID_NUMBER) {
229  // If we updated an existing page by inserting the new page into the
230  // used list, we need to write it out.
231  writePage(existing_page.page_number(), existing_page.header_, existing_page);
232  }
233  writeHeader(header);
234 
235  return new_page;
236 }
void writeHeader(const FileHeader &header)
Definition: file.cpp:125
std::uint32_t PageId
Identifier for a page in a file.
Definition: types.h:15
void writePage(const PageId page_number, const Page &new_page)
Definition: file.cpp:260
Page readPage(const PageId page_number) const
Definition: file.cpp:238
FileIterator end()
Definition: file.cpp:312
static const PageId INVALID_NUMBER
Definition: page.h:124
FileIterator begin()
Definition: file.cpp:307
FileHeader readHeader() const
Definition: file.cpp:118
FileIterator badgerdb::PageFile::begin ( )

Returns an iterator at the first page in the file.

Returns
Iterator at first page of file.

Definition at line 307 of file file.cpp.

307  {
308  const FileHeader& header = readHeader();
309  return FileIterator(this, header.first_used_page);
310 }
FileHeader readHeader() const
Definition: file.cpp:118
void badgerdb::File::close ( )
protectedinherited

Closes the underlying file stream in <stream_>. This method only closes the file if no other File objects exist that access the same file.

Definition at line 105 of file file.cpp.

105  {
106  if(open_counts_[filename_] > 0)
108 
109  stream_.reset();
110  assert(open_counts_[filename_] >= 0);
111 
112  if (open_counts_[filename_] == 0) {
113  open_streams_.erase(filename_);
114  open_counts_.erase(filename_);
115  }
116 }
static CountMap open_counts_
Definition: file.h:224
std::string filename_
Definition: file.h:229
std::shared_ptr< std::fstream > stream_
Definition: file.h:234
static StreamMap open_streams_
Definition: file.h:219
PageFile badgerdb::PageFile::create ( const std::string &  filename)
static

Creates a new file.

Parameters
filenameName of the file.
Exceptions
FileExistsExceptionIf the requested file already exists.

Definition at line 135 of file file.cpp.

135  {
136  return PageFile(filename, true /* create_new */);
137 }
const std::string & filename() const
Definition: file.h:158
PageFile(const std::string &name, const bool create_new)
Definition: file.cpp:143
void badgerdb::PageFile::deletePage ( const PageId  page_number)
virtual

Deletes a page from the file.

Parameters
page_numberNumber of page to delete.

Implements badgerdb::File.

Definition at line 276 of file file.cpp.

276  {
277  FileHeader header = readHeader();
278 
279  Page existing_page = readPage(page_number);
280  Page previous_page;
281  // If this page is the head of the used list, update the header to point to
282  // the next page in line.
283  if (page_number == header.first_used_page) {
284  header.first_used_page = existing_page.next_page_number();
285  } else {
286  // Walk the used list so we can update the page that points to this one.
287  for (FileIterator iter = begin(); iter != end(); ++iter) {
288  previous_page = *iter;
289  if (previous_page.next_page_number() == existing_page.page_number()) {
290  previous_page.set_next_page_number(existing_page.next_page_number());
291  break;
292  }
293  }
294  }
295  // Clear the page and add it to the head of the free list.
296  existing_page.initialize();
297  existing_page.set_next_page_number(header.first_free_page);
298  header.first_free_page = page_number;
299  ++header.num_free_pages;
300  if (previous_page.isUsed()) {
301  writePage(previous_page.page_number(), previous_page.header_, previous_page);
302  }
303  writePage(page_number, existing_page.header_, existing_page);
304  writeHeader(header);
305 }
void writeHeader(const FileHeader &header)
Definition: file.cpp:125
void writePage(const PageId page_number, const Page &new_page)
Definition: file.cpp:260
Page readPage(const PageId page_number) const
Definition: file.cpp:238
FileIterator end()
Definition: file.cpp:312
FileIterator begin()
Definition: file.cpp:307
FileHeader readHeader() const
Definition: file.cpp:118
FileIterator badgerdb::PageFile::end ( )

Returns an iterator representing the page after the last page in the file. This iterator should not be dereferenced.

Returns
Iterator representing page after the last page in the file.

Definition at line 312 of file file.cpp.

312  {
313  return FileIterator(this, Page::INVALID_NUMBER);
314 }
static const PageId INVALID_NUMBER
Definition: page.h:124
bool badgerdb::File::exists ( const std::string &  filename)
staticinherited

Returns true if the file exists and is open.

Parameters
filenameName of the file.

Definition at line 46 of file file.cpp.

46  {
47  std::fstream file(filename);
48  if(file)
49  {
50  file.close();
51  return true;
52  }
53 
54  return false;
55 }
const std::string & filename() const
Definition: file.h:158
const std::string& badgerdb::File::filename ( ) const
inlineinherited

Returns the name of the file this object represents.

Returns
Name of file.

Definition at line 158 of file file.h.

158 { return filename_; }
std::string filename_
Definition: file.h:229
PageId badgerdb::File::getFirstPageNo ( )
inherited

Returns pageid of first page in the file.

Returns
Iterator at first page of file.

Definition at line 62 of file file.cpp.

62  {
63  const FileHeader& header = readHeader();
64  return header.first_used_page;
65 }
FileHeader readHeader() const
Definition: file.cpp:118
bool badgerdb::File::isOpen ( const std::string &  filename)
staticinherited

Returns true if the file exists and is open.

Parameters
filenameName of the file.

Definition at line 39 of file file.cpp.

39  {
40  if (!exists(filename)) {
41  return false;
42  }
43  return open_counts_.find(filename) != open_counts_.end();
44 }
static CountMap open_counts_
Definition: file.h:224
const std::string & filename() const
Definition: file.h:158
static bool exists(const std::string &filename)
Definition: file.cpp:46
PageFile badgerdb::PageFile::open ( const std::string &  filename)
static

Opens the file named fileName and returns the corresponding File object. It first checks if the file is already open. If so, then the new File object created uses the same input-output stream to read to or write fom that already open file. Reference count (open_counts_ static variable inside the File object) is incremented whenever an already open file is opened again. Otherwise the UNIX file is actually opened. The fileName and the stream associated with this File object are inserted into the open_streams_ map.

Parameters
filenameName of the file.
Exceptions
FileNotFoundExceptionIf the requested file doesn't exist.

Definition at line 139 of file file.cpp.

139  {
140  return PageFile(filename, false /* create_new */);
141 }
const std::string & filename() const
Definition: file.h:158
PageFile(const std::string &name, const bool create_new)
Definition: file.cpp:143
void badgerdb::File::openIfNeeded ( const bool  create_new)
protectedinherited

Opens the underlying file named in filename_. This method only opens the file if no other File objects exist that access the same filesystem file; otherwise, it reuses the existing stream.

Parameters
create_newWhether to create a new file.
Exceptions
FileExistsExceptionIf the underlying file exists and create_new is true.
FileNotFoundExceptionIf the underlying file doesn't exist and create_new is false.

Definition at line 78 of file file.cpp.

78  {
79  if (open_counts_.find(filename_) != open_counts_.end()) { //exists an entry already
82  } else {
83  std::ios_base::openmode mode =
84  std::fstream::in | std::fstream::out | std::fstream::binary;
85  const bool already_exists = exists(filename_);
86  if (create_new) {
87  // Error if we try to overwrite an existing file.
88  if (already_exists) {
89  throw FileExistsException(filename_);
90  }
91  // New files have to be truncated on open.
92  mode = mode | std::fstream::trunc;
93  } else {
94  // Error if we try to open a file that doesn't exist.
95  if (!already_exists) {
96  throw FileNotFoundException(filename_);
97  }
98  }
99  stream_.reset(new std::fstream(filename_, mode));
101  open_counts_[filename_] = 1;
102  }
103 }
static CountMap open_counts_
Definition: file.h:224
std::string filename_
Definition: file.h:229
std::shared_ptr< std::fstream > stream_
Definition: file.h:234
static StreamMap open_streams_
Definition: file.h:219
static bool exists(const std::string &filename)
Definition: file.cpp:46
PageFile & badgerdb::PageFile::operator= ( const PageFile rhs)

Assignment operator.

Parameters
rhsFile object to assign.
Returns
Newly assigned file object.

Definition at line 156 of file file.cpp.

156  {
157  // This accounts for self-assignment and assignment of a File object for the
158  // same file.
159  close(); //close my file and associate me with the new one
160  filename_ = rhs.filename_;
161  openIfNeeded(false /* create_new */);
162  return *this;
163 }
std::string filename_
Definition: file.h:229
void openIfNeeded(const bool create_new)
Definition: file.cpp:78
void close()
Definition: file.cpp:105
static std::streampos badgerdb::File::pagePosition ( const PageId  page_number)
inlinestaticprotectedinherited

Returns the position of the page with the given number in the file (as an offset from the beginning of the file).

Parameters
page_numberNumber of page.
Returns
Position of page in file.

Definition at line 175 of file file.h.

175  {
176  return sizeof(FileHeader) + ((page_number - 1) * Page::SIZE);
177  }
static const std::size_t SIZE
Definition: page.h:114
FileHeader badgerdb::File::readHeader ( ) const
protectedinherited

Reads the header for this file from disk.

Returns
The file header.

Definition at line 118 of file file.cpp.

118  {
119  FileHeader header;
120  stream_->seekg(0 /* pos */, std::ios::beg);
121  stream_->read(reinterpret_cast<char*>(&header), sizeof(FileHeader));
122  return header;
123 }
std::shared_ptr< std::fstream > stream_
Definition: file.h:234
Page badgerdb::PageFile::readPage ( const PageId  page_number) const
virtual

Reads an existing page from the file.

Parameters
page_numberNumber of page to read.
Returns
The page.
Exceptions
InvalidPageExceptionIf the page doesn't exist in the file or is not currently used.

Implements badgerdb::File.

Definition at line 238 of file file.cpp.

238  {
239  FileHeader header = readHeader();
240 
241  if (page_number >= header.num_pages)
242  {
243  throw InvalidPageException(page_number, filename_);
244  }
245  return readPage(page_number, false /* allow_free */);
246 }
std::string filename_
Definition: file.h:229
Page readPage(const PageId page_number) const
Definition: file.cpp:238
FileHeader readHeader() const
Definition: file.cpp:118
void badgerdb::File::remove ( const std::string &  filename)
staticinherited

Deletes an existing file.

Parameters
filenameName of the file.
Exceptions
FileNotFoundExceptionIf the file doesn't exist.
FileOpenExceptionIf the file is currently open.

Definition at line 29 of file file.cpp.

29  {
30  if (!exists(filename)) {
31  throw FileNotFoundException(filename);
32  }
33  if (isOpen(filename)) {
34  throw FileOpenException(filename);
35  }
36  std::remove(filename.c_str());
37 }
static bool isOpen(const std::string &filename)
Definition: file.cpp:39
const std::string & filename() const
Definition: file.h:158
static bool exists(const std::string &filename)
Definition: file.cpp:46
void badgerdb::File::writeHeader ( const FileHeader header)
protectedinherited

Writes the given header to the disk as the header for this file.

Parameters
headerFile header to write.

Definition at line 125 of file file.cpp.

125  {
126  stream_->seekp(0 /* pos */, std::ios::beg);
127  stream_->write(reinterpret_cast<const char*>(&header), sizeof(FileHeader));
128  stream_->flush();
129 }
std::shared_ptr< std::fstream > stream_
Definition: file.h:234
void badgerdb::PageFile::writePage ( const PageId  page_number,
const Page new_page 
)
virtual

Writes a page into the file at the given page number. No bounds checking is performed.

Parameters
page_numberNumber of page whose contents to replace.
new_pagePage to write.

Implements badgerdb::File.

Definition at line 260 of file file.cpp.

260  {
261  PageHeader header = readPageHeader(new_page_number);
262  if (header.current_page_number == Page::INVALID_NUMBER)
263  {
264  // Page has been deleted since it was read.
265  throw InvalidPageException(new_page_number, filename_);
266  }
267  // Page on disk may have had its next page pointer updated since it was read;
268  // we don't modify that, but we do keep all the other modifications to the
269  // page header.
270  const PageId next_page_number = header.next_page_number;
271  header = new_page.header_;
272  header.next_page_number = next_page_number;
273  writePage(new_page_number, header, new_page);
274 }
std::string filename_
Definition: file.h:229
std::uint32_t PageId
Identifier for a page in a file.
Definition: types.h:15
void writePage(const PageId page_number, const Page &new_page)
Definition: file.cpp:260
static const PageId INVALID_NUMBER
Definition: page.h:124

Member Data Documentation

std::string badgerdb::File::filename_
protectedinherited

Name of the file this object represents.

Definition at line 229 of file file.h.

File::CountMap badgerdb::File::open_counts_
staticprotectedinherited

Counts for opened files.

Definition at line 224 of file file.h.

File::StreamMap badgerdb::File::open_streams_
staticprotectedinherited

Streams for opened files.

Definition at line 219 of file file.h.

std::shared_ptr<std::fstream> badgerdb::File::stream_
protectedinherited

Stream for underlying filesystem object.

Definition at line 234 of file file.h.


The documentation for this class was generated from the following files: