BadgerDB
 All Classes Namespaces Functions Variables Typedefs Friends Pages
Public Member Functions | Static Public Member Functions | Friends | List of all members
badgerdb::File Class Reference

Class which represents a file in the filesystem containing database pages. More...

#include <file.h>

Public Member Functions

 File (const File &other)
 
Fileoperator= (const File &rhs)
 
 ~File ()
 
Page allocatePage ()
 
Page readPage (const PageId page_number) const
 
void writePage (const Page &new_page)
 
void deletePage (const PageId page_number)
 
const std::string & filename () const
 
FileIterator begin ()
 
FileIterator end ()
 

Static Public Member Functions

static File create (const std::string &filename)
 
static File 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)
 

Friends

class FileIterator
 
class FileTest
 

Detailed Description

Class which represents a file in the filesystem containing database pages.

The File class wraps a stream to an underlying file on disk. Files contain fixed-sized pages, and they never deallocate space (though they do reuse deleted pages if possible). If multiple File objects refer to the same underlying file, they will share the stream in memory. If a file that has already been opened (possibly by another query), then the File class detects this (by looking in the open_streams_ map) and just returns a file object with the already created stream for the file without actually opening the UNIX file again.

Warning
This class is not threadsafe.

Definition at line 73 of file file.h.

Constructor & Destructor Documentation

badgerdb::File::File ( const File other)

Copy constructor.

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

Definition at line 65 of file file.cpp.

66  : filename_(other.filename_),
67  stream_(open_streams_[filename_]) {
68  ++open_counts_[filename_];
69 }
badgerdb::File::~File ( )

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

Definition at line 80 of file file.cpp.

80  {
81  close();
82 }

Member Function Documentation

Page badgerdb::File::allocatePage ( )

Allocates a new page in the file.

Returns
The new page.

Definition at line 84 of file file.cpp.

84  {
85  FileHeader header = readHeader();
86  Page new_page;
87  Page existing_page;
88  if (header.num_free_pages > 0) {
89  new_page = readPage(header.first_free_page, true /* allow_free */);
90  new_page.set_page_number(header.first_free_page);
91  header.first_free_page = new_page.next_page_number();
92  --header.num_free_pages;
93 
94  if (header.first_used_page == Page::INVALID_NUMBER ||
95  header.first_used_page > new_page.page_number()) {
96  // Either have no pages used or the head of the used list is a page later
97  // than the one we just allocated, so add the new page to the head.
98  if (header.first_used_page > new_page.page_number()) {
99  new_page.set_next_page_number(header.first_used_page);
100  }
101  header.first_used_page = new_page.page_number();
102  } else {
103  // New page is reused from somewhere after the beginning, so we need to
104  // find where in the used list to insert it.
105  PageId next_page_number = Page::INVALID_NUMBER;
106  for (FileIterator iter = begin(); iter != end(); ++iter) {
107  next_page_number = (*iter).next_page_number();
108  if (next_page_number > new_page.page_number() ||
109  next_page_number == Page::INVALID_NUMBER) {
110  existing_page = *iter;
111  break;
112  }
113  }
114  existing_page.set_next_page_number(new_page.page_number());
115  new_page.set_next_page_number(next_page_number);
116  }
117 
118  assert((header.num_free_pages == 0) ==
119  (header.first_free_page == Page::INVALID_NUMBER));
120  } else {
121  new_page.set_page_number(header.num_pages);
122  if (header.first_used_page == Page::INVALID_NUMBER) {
123  header.first_used_page = new_page.page_number();
124  } else {
125  // If we have pages allocated, we need to add the new page to the tail
126  // of the linked list.
127  for (FileIterator iter = begin(); iter != end(); ++iter) {
128  if ((*iter).next_page_number() == Page::INVALID_NUMBER) {
129  existing_page = *iter;
130  break;
131  }
132  }
133  assert(existing_page.isUsed());
134  existing_page.set_next_page_number(new_page.page_number());
135  }
136  ++header.num_pages;
137  }
138  writePage(new_page.page_number(), new_page);
139  if (existing_page.page_number() != Page::INVALID_NUMBER) {
140  // If we updated an existing page by inserting the new page into the
141  // used list, we need to write it out.
142  writePage(existing_page.page_number(), existing_page);
143  }
144  writeHeader(header);
145 
146  return new_page;
147 }
FileIterator begin()
Definition: file.cpp:214
FileIterator end()
Definition: file.cpp:219
std::uint32_t PageId
Identifier for a page in a file.
Definition: types.h:15
void writePage(const Page &new_page)
Definition: file.cpp:169
Page readPage(const PageId page_number) const
Definition: file.cpp:149
static const PageId INVALID_NUMBER
Definition: page.h:123
FileIterator badgerdb::File::begin ( )

Returns an iterator at the first page in the file.

Returns
Iterator at first page of file.

Definition at line 214 of file file.cpp.

214  {
215  const FileHeader& header = readHeader();
216  return FileIterator(this, header.first_used_page);
217 }
File badgerdb::File::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 29 of file file.cpp.

29  {
30  return File(filename, true /* create_new */);
31 }
const std::string & filename() const
Definition: file.h:179
File(const File &other)
Definition: file.cpp:65
void badgerdb::File::deletePage ( const PageId  page_number)

Deletes a page from the file.

Parameters
page_numberNumber of page to delete.

Definition at line 184 of file file.cpp.

184  {
185  FileHeader header = readHeader();
186  Page existing_page = readPage(page_number);
187  Page previous_page;
188  // If this page is the head of the used list, update the header to point to
189  // the next page in line.
190  if (page_number == header.first_used_page) {
191  header.first_used_page = existing_page.next_page_number();
192  } else {
193  // Walk the used list so we can update the page that points to this one.
194  for (FileIterator iter = begin(); iter != end(); ++iter) {
195  previous_page = *iter;
196  if (previous_page.next_page_number() == existing_page.page_number()) {
197  previous_page.set_next_page_number(existing_page.next_page_number());
198  break;
199  }
200  }
201  }
202  // Clear the page and add it to the head of the free list.
203  existing_page.initialize();
204  existing_page.set_next_page_number(header.first_free_page);
205  header.first_free_page = page_number;
206  ++header.num_free_pages;
207  if (previous_page.isUsed()) {
208  writePage(previous_page.page_number(), previous_page);
209  }
210  writePage(page_number, existing_page);
211  writeHeader(header);
212 }
FileIterator begin()
Definition: file.cpp:214
FileIterator end()
Definition: file.cpp:219
void writePage(const Page &new_page)
Definition: file.cpp:169
Page readPage(const PageId page_number) const
Definition: file.cpp:149
FileIterator badgerdb::File::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 219 of file file.cpp.

219  {
220  return FileIterator(this, Page::INVALID_NUMBER);
221 }
static const PageId INVALID_NUMBER
Definition: page.h:123
bool badgerdb::File::exists ( const std::string &  filename)
static

Returns true if the file exists and is open.

Parameters
filenameName of the file.

Definition at line 54 of file file.cpp.

54  {
55  std::fstream file(filename);
56  if(file)
57  {
58  file.close();
59  return true;
60  }
61 
62  return false;
63 }
const std::string & filename() const
Definition: file.h:179
const std::string& badgerdb::File::filename ( ) const
inline

Returns the name of the file this object represents.

Returns
Name of file.

Definition at line 179 of file file.h.

179 { return filename_; }
bool badgerdb::File::isOpen ( const std::string &  filename)
static

Returns true if the file exists and is open.

Parameters
filenameName of the file.

Definition at line 47 of file file.cpp.

47  {
48  if (!exists(filename)) {
49  return false;
50  }
51  return open_counts_.find(filename) != open_counts_.end();
52 }
const std::string & filename() const
Definition: file.h:179
static bool exists(const std::string &filename)
Definition: file.cpp:54
File badgerdb::File::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 33 of file file.cpp.

33  {
34  return File(filename, false /* create_new */);
35 }
const std::string & filename() const
Definition: file.h:179
File(const File &other)
Definition: file.cpp:65
File & badgerdb::File::operator= ( const File rhs)

Assignment operator.

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

Definition at line 71 of file file.cpp.

71  {
72  // This accounts for self-assignment and assignment of a File object for the
73  // same file.
74  close(); //close my file and associate me with the new one
75  filename_ = rhs.filename_;
76  openIfNeeded(false /* create_new */);
77  return *this;
78 }
Page badgerdb::File::readPage ( const PageId  page_number) const

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.

Definition at line 149 of file file.cpp.

149  {
150  FileHeader header = readHeader();
151  if (page_number >= header.num_pages) {
152  throw InvalidPageException(page_number, filename_);
153  }
154  return readPage(page_number, false /* allow_free */);
155 }
Page readPage(const PageId page_number) const
Definition: file.cpp:149
void badgerdb::File::remove ( const std::string &  filename)
static

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 37 of file file.cpp.

37  {
38  if (!exists(filename)) {
39  throw FileNotFoundException(filename);
40  }
41  if (isOpen(filename)) {
42  throw FileOpenException(filename);
43  }
44  std::remove(filename.c_str());
45 }
static bool isOpen(const std::string &filename)
Definition: file.cpp:47
const std::string & filename() const
Definition: file.h:179
static bool exists(const std::string &filename)
Definition: file.cpp:54
void badgerdb::File::writePage ( const Page new_page)

Writes a page into the file, replacing any existing contents. The page must have been already allocated in this file by a call to allocatePage().

See Also
allocatePage()
Parameters
new_pagePage to write.

Definition at line 169 of file file.cpp.

169  {
170  PageHeader header = readPageHeader(new_page.page_number());
171  if (header.current_page_number == Page::INVALID_NUMBER) {
172  // Page has been deleted since it was read.
173  throw InvalidPageException(new_page.page_number(), filename_);
174  }
175  // Page on disk may have had its next page pointer updated since it was read;
176  // we don't modify that, but we do keep all the other modifications to the
177  // page header.
178  const PageId next_page_number = header.next_page_number;
179  header = new_page.header_;
180  header.next_page_number = next_page_number;
181  writePage(new_page.page_number(), header, new_page);
182 }
std::uint32_t PageId
Identifier for a page in a file.
Definition: types.h:15
void writePage(const Page &new_page)
Definition: file.cpp:169
static const PageId INVALID_NUMBER
Definition: page.h:123

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