#define INT_TYPE 0
#define STR_TYPE 1
typedef struct Object {
void* data;
struct Object* nextObj;
}Object;
typedef struct Table {
Object** arr;
int dataType;
int listLen;
int originalSize;
int ratio;
int currentSize;
int timesDup; // Number of times the table duplicated.
}Table;
/**
* The function gets the original size, the type of the data in the table elements and the maximum number of element in each entry.
* it initializes the Table struct members.
* On success, the function returns a pointer to the new created Table, otherwise, it returns NULL.
*/
Table* createTable(int size, int dType, int listLength);
/**
* The function release all the allocated members of struct Table.
*/
void freeTable(Table* table);
/**
* The function adds data to the hashtable (as described in the exe definition)
* On success, the function returns the array index of the added data, otherwise, it return -1.
*/
int add(Table* table, void* data);
/**
* The function removes the Object which its data equals to data, if there are more than one, it removes the first one.
* On success, the function returns the array index of the removed data, otherwise, it returns -1.
* -1 is also returned in the case where there is no such object.
*/
int removeObj(Table* table, void* data);
/**
* The function searches for an object that its data is equal to given data and returns a pointer to that object.
* If there is no such object or in a case of an error, NULL is returned.
*/
Object* search(Table* table, void* data);
/**
* The function prints the table (the format is in the exe definition)
*/
void printTable(Table* table);
/**
* This function creates an object and returns the pointer to it or NULL if there is some error.
*/
Object* createObject(void* data);
/**
* This function frees an object, note the if you allocated the data inside the element, it should also be freed.
* the type parameter is given for cases where not all types are dynamically allocated during Object creation.
*/
void freeObject(Object* obj, int type);
/**
* check the equality of the data of two objects. The implementation is different depending the type of the data.
* the function returns 0 if they are equal or some other value if they are not equal.
*/
int isEqual(int type, void* data1, void* data2);
/**
* returns the hash value of an integer, which is key mod origSize
*/
int intHashFun(int* key, int origSize);
/**
* returns the hash value of an string, which is m mod origSize, where m is the sum of the ascii value of all the
* character in key.
*/
int strHashFun(char* key, int origSize);
/**
* The function gets the table pointer and duplicated it's size, it also moves all the original data to their new location.
*/
void duplicateTable(Table *table);
/**
* The function gets the list pointer and counts elements in the list.
*/
int listLength(Object* obj);