BadgerDB
 All Classes Namespaces Functions Variables Typedefs Friends Pages
BadgerDB Documentation

Table of contents

  1. File layout
  2. Building and modifying the system
    1. Prerequisites
    2. Executing a build
    3. Modifying and running main
    4. Rebuilding the documentation
  3. BadgerDB API
    1. File storage
      1. Creating, opening, and deleting files
      2. Reading and writing data in a file
      3. Reading and writing data in a page

File layout

The files in this package are organized under the following hierarchy:

docs/                  generated documentation
src/                   code for BadgerDB

You will likely be most interested in src

Building and modifying the system

Prerequisites

To build and run the system, you need the following packages:

The build system is configured to work on CSL RedHat 5 and 6 machines out of the box.

Executing a build

All command examples are meant to be run at the command prompt from the badgerdb directory. When executing a command, omit the $ prompt (so “$ make” means you just type “make” and press enter).

To build the executable:

$ make

Modifying and running main

To run the executable, first build the code, then run:

$ ./src/badgerdb_main

If you want to edit what badgerdb_main does, edit src/main.cpp.

Rebuilding the documentation

Documentation is generated by using Doxygen. If you have updated the documentation and need to regenerate the output files, run:

$ make doc

Resulting documentation will be placed in the docs/ directory; open index.html with your web browser to view it.

BadgerDB API

File storage

Interaction with the underlying filesystem is handled by two classes: File and Page. Files store zero or more fixed-length pages; each page holds zero or more variable-length records.

Record data is represented using std::strings of arbitrary characters.

Creating, opening, and deleting files

Files must first be created before they can be used:

// Create and open a new file with the name "filename.db".
badgerdb::File new_file = badgerdb::File::create("filename.db");

If you want to open an existing file, use File::open like so:

// Open an existing file with the name "filename.db".
badgerdb::File existing_file = badgerdb::File::open("filename.db");

Multiple File objects share the same stream to the underlying file. The stream will be automatically closed when the last File object is out of scope; no explicit close command is necessary.

You can delete a file with File::remove:

// Delete a file with the name "filename.db".
badgerdb::File::remove("filename.db");

Reading and writing data in a file

Data is added to a File by first allocating a Page, populating it with data, and then writing the Page back to the File.

For example:

#include "file.h"
...
// Write a record with the value "hello, world!" to the file.
badgerdb::File db_file = badgerdb::File::open("filename.db");
badgerdb::Page new_page = db_file.allocatePage();
new_page.insertRecord("hello, world!");
db_file.writePage(new_page);

Pages are read back from a File using their page numbers:

#include "file.h"
#include "page.h"
...
// Allocate a page and then read it back.
badgerdb::Page new_page = db_file.allocatePage();
db_file.writePage(new_page);
const badgerdb::PageId& page_number = new_page.page_number();
badgerdb::Page same_page = db_file.readPage(page_number);

You can also iterate through all pages in the File:

#include "file_iterator.h"
...
for (badgerdb::FileIterator iter = db_file.begin();
iter != db_file.end();
++iter) {
std::cout << "Read page: " << iter->page_number() << std::endl;
}

Reading and writing data in a page

Pages hold variable-length records containing arbitrary data.

To insert data on a page:

#include "page.h"
...
badgerdb::Page new_page;
new_page.insertRecord("hello, world!");

Data is read by using RecordIds, which are provided when data is inserted:

#include "page.h"
...
badgerdb::Page new_page;
const badgerdb::RecordId& rid = new_page.insertRecord("hello, world!");
new_page.getRecord(rid); // returns "hello, world!"

As Pages use std::string to represent data, it's very natural to insert strings; however, any data can be stored:

#include "page.h"
...
struct Point {
int x;
int y;
};
Point new_point = {10, -5};
badgerdb::Page new_page;
std::string new_data(reinterpret_cast<char*>(&new_point),
sizeof(new_point));
const badgerdb::RecordId& rid = new_page.insertRecord(new_data);
Point read_point =
*reinterpret_cast<const Point*>(new_page.getRecord(rid).data());

Note that serializing structures like this is not industrial strength; it's better to use something like Google's protocol buffers or Boost serialization.

You can also iterate through all records in the Page:

#include "page_iterator.h"
...
for (badgerdb::PageIterator iter = new_page.begin();
iter != new_page.end();
++iter) {
std::cout << "Record data: " << *iter << std::endl;
}