#include #define PAGESIZE 131072 // this gives the three attribute types for our "database": Int, Double, and String enum Type {Int, Double, String}; struct Attribute { char *data; int length; Attribute (); ~Attribute (); // write the attribute in a "flat" format to the specified memory location; // returns the length of the record, in bytes int ToBinary (char *writeToHere); // read the attribute from the flat, binary format; returns the number of // bytes that were read int FromBinary (char *readFromHere); }; class Schema; // This is the "in memory" version of a record; that is, once a record has been // read from disk and is sitting in memory, it will sit inside of this particular // structure class Record { Attribute *myAtts; int numAtts; public: Record (); ~Record(); // prints the contents of the record to the screen; this requires // that the schema also be given so that the record can be interpreted void Print (Schema &mySchema); // reads the next record from a pointer to a text file; also requires // that the schema be given; returns a 0 if there is no data left or // if there is an error and returns a 1 otherwise int SuckNextRecord (Schema &mySchema, FILE *textFile); // suck the contents of the record fromMe into this; note that after // this call, fromMe will no longer have anything inside of it // and fromMe.myAtts should be 0 void Consume (Record &fromMe); // make a copy of the record fromMe; note that this is far more // expensive (requiring a bit-by-bit copy) than Consume, which is // only a pointer operation void Copy (Record ©Me); // write the record in a "flat" format to the specified memory location; // returns the length of the record, in bytes int ToBinary (char *writeToHere); // read the record from the flat, binary format; returns the number of // bytes that were read int FromBinary (char *readFromHere); // this returns the number of bytes that would be needed to store the // record in a flat format int HowManyBytes (); }; class Page { // use whatever container stuff you want here; basically, you need // to choose some data structure (like a linked list) that allows you // to manange a set of Record objects public: // this is the constructor; the arg tells the page how many bytes it // is allowed to store Page (int maxSizeInBytes); ~Page (); // this takes a page and writes its binary representation to bits void ToBinary (char *bits); // this takes a binary representation of a page and gets the // records from it void FromBinary (char *bits); // the deletes the first record from a page and returns it; returns // a zero if there were no records on the page int GetFirst (Record &firstOne); // this appends the record to the end of a page. The return value // is a one on success and a zero if there is no more space. // Note that the record is consumed so it will have no value after int Append (Record &addMe); // empty out the page so that it contains no records void EmptyItOut (); }; class File { public: // returns the current length of the file, in pages int GetLength (); // opens the given file; the first parameter tells whether or not to // create the file. If the parameter is zero, a new file is created // the file; if notNew is zero, then the file is created and any other // file located at that location is erased. Otherwise, the file is // simply opened void Open (int notNew, char *fName); // moves the record "pointer" in the file to the first record on // the specified page in the file void MovePointer (int whichPage); // gets the next record in the file; returns a 0 if there are no more // records and a 1 otherwise int NextRec (Record &getMe); // adds a new record to the very end of the file; this also updates // the current "pointer" so that it is pointing just past the end of the file void Append (Record &addMe); // allows someone to explicitly get a specified page from the file void GetPage (Page &putItHere, int whichPage); // allows someone to explicitly write a specified page to the file; // if the write is past the end of the file, all of the new pages that // are before the page to be written are zeroed out void AddPage (Page &addMe, int whichPage); // closes the file and returns the file length (in number of pages) int Close (); File (); ~File (); }; class Schema { public: // this function goes to the text file called fName and loads in // the schema for relation relName Schema (char *relName, char *fName); ~Schema (); // this tries to find the specified attribute and returns a 1 or a 0 // depending upon whether or not the attribute has been found int Find (char *attName); // this gets the type of the given attribute Type GetType (char *attName); }; class Predicate { public: // this function goes to the specified text file and creates a // selection predicate corresponding to the file Predicate (Schema &useMe, char *fNAme); ~Predicate (); // returns 1 or TRUE if the predicate accepts the given record, // and returns a 0 or FALSE if the predicate does not accept the // given record int Apply (Record &toMe); };