You will implement parts of the SwatDB Database Management System, as lab assignments in CS44. This page includes some general information about SwatDB, its structure, and links to its documentation.

1. About SwatDB

SwatDB is user-level Database Management System and Courseware designed for learning how a DBMS works by implementing parts of one.

SwatDB was started in the Summer of 2020, with the purpose of using it for CS44 lab assignments. It continues to be under development as we add more features and functionality.

SwatDB is copyrighted software, and as such, you are not allowed to distribute any parts of it:

Copyright (c) 2020 Swarthmore College Computer Science
Department, Swarthmore PA, Professors Tia Newhall, Ameet Soni

SwatDB Contributors include:

  • Keonwoo Oh'21

  • Herbert Rand'21

  • Professors Tia Newhall and Ameet Soni

2. SwatDB Structure

SwatDB is implemented using a layered architecture as shown in this figure:

SwatDB

The layers include:

  • Disk Manger: manages SwatDB stored data on disk, and implements an interface to create/delete a DB file and to allocate/deallocate, read/write Pages from disk. (The Disk Manager part of SwatDB stores SwatDB files in Unix files),

  • Buffer Manger: manages SwatDB main memory as a Buffer Pool of Pages, and implements an interface to higher layers for accessing Pages of Memory, including: allocate/deallocatePage, get/release/fushPage.

  • File Manager: manages files and indices in SwatDB. Its main interface is to create/deleteFile or Index.

  • Relational Operator Manager: implements operations on stored DB files and indices in response to a query. This layer is not yet implemented.

  • SwatDB: is the top-level layer of the system. It provides interface methods for initializing the system and to get access to main parts of the system. Eventually, it will implement a more rich user-interface to SwatDB.

In addition to the layers, there are two SwatDB modules that are used by several layers of the system:

  • The Catalog: keeps state about the stored DB in the system, including Schema for all stored relations and indices, and internal data for accessing their file data.

  • The Lock Manager: manages Page and File locks in the system.

Currently, not all parts of SwatDB are fully implemented.

3. SwatDB in CS44 Labs

Some lab assignments will involve implementing a layer or partial layer of SwatDB. For these assignments, your implementation will replace the default SwatDB implementation. We will provide a Makefile that compiles your implementation and links in existing SwatDB implementations of remaining layers into test program executables.

For these lab assignments, we will give you the .h and .cpp files to implement. Sometimes these interfaces are slightly simplified from the true SwatDB implementation of the layer, so make sure to read the .h file we give you for the interface you must implement rather than the .h file from the SwatDB documentation. The remaining interfaces for other parts of SwatDB can be viewed using the SwatDB documentation.

4. SwatDB Documentation

Here is the link to the on-line documentation for SwatDB:

You can view information about any of its classes under the Classes menu, and from .h files under the Files menu (including viewing the full source of all of its header files).

Remember that for lab assignments that you should look at class and type definitions in the the .h files that we give you in your repo as the definitions you need to implement, and not their corresponding ones from the SwatDB documentation.

For lab assignments, we may have you implement SwatDB classes slightly differently from how they are implemented in the SwatDB system (often removing some optimized or concurrent functionality from their SwatDB implementation). You want to be sure you are implementing the required functionality for the lab and not the internal SwatDB version if they differ.

SwatDB Documentation is generated from its header files using Doxygen. If you note in header files we give you comments start with /** and use some keywords like @param and @returns. These are doxygen style comments from which doxygen generates code documentation.

5. Key SwatDB Files and Interfaces

The following are some of the main definitions, types, and classes in SwatDB. In general, if SwatDB defines a typedef or constant, use that definition rather than the underlying type or value.

5.1. System-wide Definitions and Classes

The following classes define the main types and interfaces used throughout the SwatDB system.

  • swatdb_types.h contains typedefs, constants, and structs that are used throughout SwatDB.

  • The Page class is a base class for all file and index specific page types in the system. It defines the main unit of storage in the system: a Page of file data, a Page of memory, etc.

  • The File class is a base class for all types of files and indices supported by SwatDB.

  • The Catalog class contains information about all stored files and indices in the DB. It is a way to get a mapping from the user-level name for a Relation on index file to its file data stored on disk. It also contains Schema information and other metadata about DB files stored in by the system.

  • The Record class defines a Record structure for a particular relation or index file. It includes a Data class object that actually stores the bytes of an individual record.

5.2. SwatDB Layers

The following classes define the interfaces to the main layers of SwatDB.

  • The SwatDB class defines the highest layer of SwatDB. It includes methods to boot/initialize and save the DB, and is an interface to to other layers of the system. For some labs, we may give you testing code that creates a SwatDB object to represent the entire system. For others, we may give you test code that implements just the parts of the system needed to test your lab solution.

  • The FileManager class defines the interface to the Disk Manger layer of SwatDB.

    • The File class is a base class for all types of files and indices supported by SwatDB. It defines a generic file interface for all types of SwatDB files and indices. The HeapFile class is an example of a derived class from File that defines the HeapFile interface.

  • The BufferManager class defines the interface to the Disk Manger layer of SwatDB.

  • The DiskManager class defines the interface to the Disk Manger layer of SwatDB.

  • The Catalog class defines the Catalog Manager interface, that is used by multiple layers of the system.

5.3. SwatDB Exceptions

The SwatDBException class is the base class for all exceptions defined by the system.

It, and all of its derived SwatDB exception classes are defined in the exceptions.h header file. To add new SwatDB exceptions, follow the model of classes derived from SwatDBException in this file.

5.3.1. SwatDB Exception Naming Convention

SwatDB Exception class names start with a description of the type of error they represent, such as InvalidPageId or InsufficientSpace. The suffix of the name represents the SwatDB layer in which the error is detected and from which the exception in thrown. For example, InvalidPageIdBufMgr is an exception thrown by the BufferManager in response to encountering a bad page identifier, and InvalidPageIdDiskMgr is an exception thrown by the DiskManager in repsonse to a similar error.

Exception classes that are not specify to a layer, do not include the layer-identifying suffix in their names.

5.3.2. Throwing SwatDB Exceptions

In your code, to throw an specific SwatDBException type look at documentation of the class in exceptions.h header file, or in the Classes documentation SwatDB Classes. Note the parameters to its constructor. You will need to pass appropriate argument values to its constructor when you call it through as part of a throw statement.

For example, to throw an InvalidPageIdBufMgr exception, the constructor takes a PageId value:

InvalidPageIdBufMgr (PageId page_id);

To throw this exception, pass a PageId value to its constructor, as in this example:

// assume pid is a PageId variable or parameter
// that is given a value in some way  before this stmt
if(pid.page_num == INVALID_PAGE_NUM) {

  throw InvalidPageIdBufMgr(pid);
}

To throw an InvalidFileIdHeapFile exception, its constructor takes a FileId value:

InvalidFileIdHeapFile (FileId file_id);

So you need to pass it a FileId value when you throw it:

FileId fid;

// assume some code is here that gives fids a value

if(fid == INVALID_FILE_ID) {
  throw InvalidPageIdBufMgr(pid);
}

5.3.3. Catching SwatDB Exceptions

If your code makes a call to a SwatDB function that throws an exception, you might want to catch it and handle the exception. To do this, call the method inside a try-catch block, and catch the specific Exception type, that your code handles. For example,

try {
  disk_mgr->getSize(fid);
}
catch (InvalidFileIdDiskMg &e) {
  // code to handle this exception
  // (could include throwing a different exception type)
}

If the called method may throw several Exception types, all of which you want to catch and handle in the same way, use the SwatDBException base class type in the catch clause.

try {
  disk_mgr->deallocatePage(pid);
}
catch(SwatDBException& e){
  // code to handle any and all exceptions
  // thrown by deallocatePage
}

Sometime when you call a method that throws an exception, you don’t want to catch it. Instead, you want to just let the exception down the stack to be caught by a higher-level layer of the system. In this case, don’t call the method in a try-catch block, and if it throws an exception it will pass down the stack when the exception is thrown (your function code will not longer exectute, sort-of like returning from a function):

disk_mgr->getSize(fid);

Sometime code you write that makes a call to a lower layer that throws exceptions that you want to pass on through, but before you do so you need to clean up some local state. In this case you need to catch any and all Exception types that may be thrown by the lower layer, then in the catch block, clean up an local state, and then re-throw whatever exception type you caught to the upper layers. Here is an example of how to do that:

 try{
   Page *cur_page = buf_mgr->getPage(pid);
 }
 catch(SwatDBException& e){
      cleanup_somestuff(pid);  // cleanup my local state
      throw;                   // then throw whatever exception I caught
 }