File Hash Map Assignment

This is basically a repeat of the previous assignment except that the data is stored in a file. As with the linked list assignment earlier, this forces us to make a few changes to how things are done. We have to remove the normal iterator and have only a const_iterator. Also, [] can't be used to set values. It is a const method that returns a mapped_type by value. To make up for this, we have a set method that will behave the way that [] did on the memory based hash map.

Open addressing (CLRS 11.4), where everything is stored in the "array", does not allow for efficient removal. As such, I have taken out the erase method. I want you to write this using open addressing for the experience of doing so and to keep the assignment shorter. You could do a file based approach using linking where you keep a pool of singly linked list nodes after the table, but I think that would take to long to write.

When you grow your table, you have to make a second file. As with the previous file based solution, you can't move more than two elements in memory at any given time. You can safely assume that if you append a 2 to the end of the file name you are initially passed that it will be safe as a temporary file for growing a bigger table. You will need to copy the result back into the original file though as that is what will be attached to if I open back up a file and expect it to contain proper data.

Your code should be in FileHashMap.h for your submission.

const char UNUSED = 255;

const char USED = 254;

template<typename K,typename V,typename Hash>

class FileHashMap {

Hash hashFunction;

// File name

// File pointer

// Number of records stored

// Capacity of the file

// Placed here to prevent copies.

FileHashMap(const FileHashMap<K,V,Hash> &that);

FileHashMap<K,V,Hash> &operator=(const FileHashMap<K,V,Hash> &that);

// Helper functions recommended

public:

typedef K key_type;

typedef V mapped_type;

typedef std::pair<K,V> value_type;

class const_iterator {

FILE *file;

unsigned cap;

unsigned loc;

void advance() {

// Code to move forward to the next used element after loc.

}

public:

const_iterator(FILE *f,unsigned c):file(f),cap(c),loc(0) {

advance();

}

const_iterator(FILE *f,unsigned c,unsigned i):file(f),cap(c),loc(i) {}

bool operator==(const const_iterator &i) const { return file==i.file && loc==i.loc; }

bool operator!=(const const_iterator &i) const { return !(*this==i); }

const std::pair<K,V> operator*() const {

// seek

std::pair<K,V> p;

// read

return p;

}

const_iterator &operator++() {

++loc;

advance();

return *this;

}

const_iterator operator++(int) {

const_iterator tmp(*this);

++(*this);

return tmp;

}

};

FileHashMap(const std::string &fname,const Hash &hf):hashFunction(hf),fileName(fname),file(fopen(fname.c_str(),"r+b")) {

if(file==nullptr) {

// open with w+b and set up the file

} else {

// read header information

}

}

~FileHashMap() {

// close the file

}

bool empty() const;

unsigned size() const;

const_iterator find(const key_type& k) const;

int count(const key_type& k) const;

std::pair<const_iterator,bool> insert(const value_type& val);

template <class InputIterator>

void insert(InputIterator first, InputIterator last) {

for(auto iter = first; iter!=last; ++iter) {

insert(*iter);

}

}

void clear();

const mapped_type operator[](const K &key) const;

const_iterator set(const value_type &val);

bool operator==(const FileHashMap<K,V,Hash>& rhs) const;

bool operator!=(const FileHashMap<K,V,Hash>& rhs) const;

const_iterator begin() const { return const_iterator(file,capacity); }

const_iterator end() const { return const_iterator(file,capacity,capacity); }

const_iterator cbegin() const { return const_iterator(file,capacity); }

const_iterator cend() const { return const_iterator(file,capacity,capacity); }

private:

void growTableAndRehash();

};