Fetch the homework here on Github classroom, you will use Github for version control and Gradescope for submission.
Homework 3
Computer Architecture I @ ShanghaiTech University
FKS Perfect Hash
In this homework, you are going to implement a FKS perfect hash.
Task1: Chained Hash Table
To begin, you need to build a hash table that resolves collisions with chaining in the hash_chaining.c
file.
The hash_chaining
struct requires the hash_parameters
member, which should be generated by calling the generate_hash_parameters()
function from the hash_parameters.c
file.
Additionally, you should use the hash_func
function defined in the hash_func.c
file as your hash function. This function takes a key, hash parameters, and the size of the hash table (m) as input, and returns an integer x between 0 and m-1. The key should then be placed in the corresponding slot at index x in the hash table.
Task2: FKS Perfect Hash
You are suggested to read https://www.cs.otago.ac.nz/cosc242/pdf/L11.pdf page 25-40 before you continue.
After building the chained hash table, you need to complete the FKS (Fredman, Komlós and Szemerédi) perfect hash (fks_level1.c fks_level2.c).
Instead of resolving collisions with linked lists, the perfect hash use small secondary hash tables that map each key in the hash table to a unique index in an array.
The FKS perfect hash function guarantees that there are no collisions among the keys, resulting in constant-time lookups.
When implementing the fks_level1_build()
function to build the Level 1 hash table for the FKS perfect hash, you should follow these steps:
-
Use the same hash parameters and table size as the chained hash table: Since you're leveraging the existing chained hash table as the Level 1 hash table for the FKS perfect hash, you should use the same hash function parameters and table size as the chained hash table.
-
Create Level 2 hash tables for non-empty slots: Iterate through each slot (linked lists) in the chained hash table. For non-empty slots, create a small secondary hash table (
fks_level2
) to handle the collisions within that slot. Assume there are keys in that slot, its size should be . For empty slots infks_level2
, their values should beFKS_LEVEL2_EMPTY
. Its hash parameters should also be generated by calling thegenerate_hash_parameters()
function. When there are collisions in Level 2 hash table, regenerate hash parameters and try again. For empty slots in the Level 1 hash table, its correspondinglevel2_tables[i]
should beNULL
.
Task3: Creating and linking with static/shared libraries
3.1 Static Library
In the Makefile, complete the rules $(STATIC_LIB): $(STATIC_OBJS)
and test_fks_static: test_fks.c $(STATIC_LIB)
.
For $(STATIC_LIB): $(STATIC_OBJS)
, a $(STATIC_LIB)
(./build/libhash.a) should be created from $(STATIC_OBJS)
.
For test_fks_static: test_fks.c $(STATIC_LIB)
, a static linked binary $(STATIC_BIN)
(/build/test_fks_static) should be create from test_fks.c
and the $(STATIC_LIB)
Make sure that $(STATIC_BIN)
does not have any shared objects dependencies. That is, ldd ./build/test_fks_static
should return not a dynamic executable
.
3.2 Shared Library
In the Makefile, complete the rules $(SHARED_LIB): $(SHARED_OBJS)
and test_fks_shared: test_fks.c $(SHARED_LIB)
.
For $(SHARED_LIB): $(SHARED_OBJS)
, a $(SHARED_LIB)
(./build/libhash.so) should be create from $(SHARED_OBJS)
.
For test_fks_shared: test_fks.c $(SHARED_LIB)
, a dynamic linked binary $(SHARED_BIN)
(/build/test_fks_shared) should be created from test_fks.c
and the $(SHARED_LIB)
Make sure that $(SHARED_BIN)
have shared object dependency to $(SHARED_LIB)
. That is, the output of ldd ./build/test_fks_dynamic
should include libhash.so => ./build/libhash.so
.