BadgerDB
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;
   }
 All Classes Namespaces Functions Variables Typedefs Friends