void test_hash_table_exists(void)
{
    // It should be possible to test for the presence of items in the hash table.
    hash_table_t table;
    create_hash_table(20, &table);

    hash_table_set("potato", 3, &table);
    hash_table_set("monkey", 8, &table);

    TEST_CHECK(hash_table_exists("potato", &table));
    TEST_CHECK(hash_table_exists("monkey", &table));
    TEST_CHECK(!hash_table_exists("radio", &table));

    destroy_hash_table(&table);
}
Пример #2
0
// Add a <key, value> pair to the cache.
// If key already exists, it will overwrite the old value.
// If maxmem capacity is exceeded, sufficient values will be removed
// from the cache to accomodate the new value.
void cache_set(cache_t cache, key_type key, val_type val, uint32_t val_size){
    
    item_t item_to_set = hash_table_find_item(cache->hash_table, key);
    // If key already exists, it will overwrite the old value.  
    if (item_to_set!=NULL){
        item_to_set->val = val;
        return;
    }

    //If maxmem capacity is exceeded, sufficient values will be removed
    if (cache_space_used(cache)+val_size >= cache->maxmem){
        cache_evict(cache);
    }

    //printf("\ncurrent_size:%u,hash_table_buckets_num:%u\n",cache->hash_table->current_size+1,(uint32_t) ((double) cache->hash_table->buckets_num*LOAD_FACTOR));
    //Check if we need to resize hash table
    if (cache->hash_table->current_size+1 > (uint32_t) ((double) cache->hash_table->buckets_num*LOAD_FACTOR)){
        resize_hash_table(cache->hash_table);

    }


    item_t item = hash_table_set(cache->hash_table, key, val, val_size);   
    node_t node = linked_list_set(cache->linked_list);

    // //connect the item in hash_table with its corresponding node in linked list
    connect_node_and_item(item,node);
    
}
void test_hash_table_get(void)
{
    // It should be possible to retrieve item values from the hash table.
    hash_table_t table;
    create_hash_table(20, &table);

    hash_table_set("potato", 3, &table);
    hash_table_set("monkey", 8, &table);

    TEST_CHECK(hash_table_get("potato", &table) == 3);
    TEST_CHECK(hash_table_get("monkey", &table) == 8);

    // TODO: the value returned by hash_table_get can be from a null pointer.
    // A default sentinel value could be returned instead e.g. -(2^30)
    // TEST_CHECK(hash_table_get("radio", &table) == -(2 << 30));

    destroy_hash_table(&table);
}
Пример #4
0
static void test_remove(void)
{
    Hash_table table;

    hash_table_init(&table);
    populate(&table);

    #define VERIFY_REMOVE_NOT_EXISTS(key)              \
      {                                                \
          int v = 234;                                 \
                                                       \
          VERIFY(!hash_table_get(&table, key, &v));    \
          VERIFY(!hash_table_remove(&table, key, &v)); \
          VERIFY(!hash_table_get(&table, key, &v));    \
          VERIFY(v == 234);                            \
      }

    #define VERIFY_REMOVE_EXISTS(key)                    \
      {                                                  \
          int v1, v2;                                    \
                                                         \
          VERIFY(hash_table_get(&table, key, &v1));      \
          VERIFY(hash_table_remove(&table, key, &v2));   \
          VERIFY(!hash_table_get(&table, key, NULL));    \
          VERIFY(!hash_table_remove(&table, key, NULL)); \
          VERIFY(v1 == v2);                              \
      }

    VERIFY_REMOVE_NOT_EXISTS("foo");
    VERIFY_REMOVE_NOT_EXISTS("on");
    VERIFY_REMOVE_NOT_EXISTS("tw");
    VERIFY_REMOVE_EXISTS("negative one");
    VERIFY_REMOVE_EXISTS("zero");
    VERIFY_REMOVE_EXISTS("one");
    VERIFY_REMOVE_EXISTS("two");
    VERIFY_REMOVE_EXISTS("three");
    VERIFY_REMOVE_EXISTS("four");
    VERIFY_REMOVE_EXISTS("five");
    VERIFY_REMOVE_EXISTS("six");
    VERIFY_REMOVE_EXISTS("seven");
    VERIFY_REMOVE_EXISTS("eight");
    VERIFY_REMOVE_EXISTS("nine");
    VERIFY_REMOVE_EXISTS("ten");
    VERIFY_REMOVE_EXISTS("");

    #undef VERIFY_REMOVE_NOT_EXISTS
    #undef VERIFY_REMOVE_EXISTS

    // The case where the key exists and val is NULL
    hash_table_set(&table, "foo", 3, NULL);
    VERIFY(hash_table_remove(&table, "foo", NULL));

    hash_table_free(&table);
}
Пример #5
0
bool hash_table_test() {
    hash_table *table = hash_table_new();
    
    if (table == NULL) {
        printf("ERROR: Could not create array\n");
        return false;
    }
    
    char *test_val_0 = "These are the times that try men's souls...";
    char *test_val_1 = "We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness.";
    char *test_val_2 = "Now, therefore, I, Gerald R. Ford, President of the United States, pursuant to the pardon power conferred upon me by Article II, Section 2, of the Constitution, have granted and by these presents do grant a full, free, and absolute pardon unto Richard Nixon for all offenses against the United States which he, Richard Nixon, has committed or may have committed or taken part in during the period from July (January) 20, 1969, through August 9, 1974.";
    
    hash_table_set(table, test_val_0, "test0", NULL);
    hash_table_set(table, test_val_1, "test1", NULL);
    hash_table_set(table, test_val_2, "another_test", NULL);
	
    char *value = hash_table_get(table, "test0");
    if (value != NULL && strcmp(value, test_val_0) != 0) {
        printf("ERROR: When reading hash table, expected \"%s\" but got \"%s\"\n", test_val_0, value);
        return false;
    }
	
    value = hash_table_get(table, "test1");
    if (value != NULL && strcmp(value, test_val_1) != 0) {
        printf("ERROR: When reading hash table, expected \"%s\" but got \"%s\"\n", test_val_1, value);
        return false;
    }
	
    value = hash_table_get(table, "another_test");
    if (value != NULL && strcmp(value, test_val_2) != 0) {
        printf("ERROR: When reading hash table, expected \"%s\" but got \"%s\"\n", test_val_2, value);
        return false;
    }
	
    hash_table_free(table);
    
    return true;
}
Пример #6
0
static void test_resize(void)
{
    Hash_table table;

    hash_table_init(&table);
    for (int i = 0; i < 512; ++i) {
        for (int j = 0; j < i; ++j) {
            int n;
            hash_table_get(&table, gen_key(j), &n);
            VERIFY(n == j);
        }
        hash_table_set(&table, gen_key(i), i, NULL);
    }
    hash_table_free(&table);
}
Пример #7
0
static void *
trace_winsys_buffer_map(struct pipe_winsys *_winsys, 
                        struct pipe_buffer *buffer,
                        unsigned usage)
{
   struct trace_winsys *tr_ws = trace_winsys(_winsys);
   struct pipe_winsys *winsys = tr_ws->winsys;
   void *map;
   
   map = winsys->buffer_map(winsys, buffer, usage);
   if(map) {
      if(usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
         assert(!hash_table_get(tr_ws->buffer_maps, buffer));
         hash_table_set(tr_ws->buffer_maps, buffer, map);
      }
   }
   
   return map;
}
Пример #8
0
int main(int argc, char *argv[]) {
	if (argc != 2) {
		fprintf(stderr, "usage: %s number_below_10000\n", argv[0]);
		exit(1);
	}

	hash_table table = hash_table_new();

	for (size_t i = 0; i < 10000; i++) {
		char *key;
		asprintf(&key, "%zu", i);
		hash_table_set(&table, key, i);
		free(key);
	}

	int *entry = hash_table_get(&table, argv[1]);
	if (entry) {
		printf("%d\n", *entry);
	} else {
		fprintf(stderr, "Not found\n");
	}
}
Пример #9
0
//Resize hash_table by a scale factor, if there are more than hash_table->load_factor*hash_table->current_size items in the hash_table
void resize_hash_table(hash_table_t hash_table){ 

    uint32_t old_buckets_num = hash_table->buckets_num;
    item_t * old_hash = hash_table->hash;

    hash_table->buckets_num = old_buckets_num * hash_table->scale_factor;   
    hash_table->hash = (item_t *) malloc((hash_table->buckets_num) * sizeof(item_t));
    assert(hash_table->hash!=NULL&&"hash_table fails to allocate");

    // Initialize all hash entries as empty in the new hash_table
    for(uint32_t i = 0; i < hash_table->buckets_num; ++i){
        hash_table->hash[i] = NULL;
    }

    //copy all the buckets from the original hash table to the new hash table
    for(uint32_t i = 0; i < old_buckets_num; ++i){
        for (item_t p = old_hash[i];p!=NULL;p=p->next){
            hash_table_set(hash_table, p->key,p->val,p->val_size);
        }
    }   
    //destroy the old hash_table
    destroy_hash(old_hash,old_buckets_num);
    free(old_hash);
}
Пример #10
0
void test_hash_table_maybe_grow(void)
{
    // It should be possible for the table to grow, preserving all previous values
    hash_table_t table;
    create_hash_table(10, &table);

    hash_table_set("Pottery_clay0", 0, &table);
    hash_table_set("Dark_smoked_gla0", 1, &table);
    hash_table_set("Pottery_clay1", 2, &table);
    hash_table_set("Dark_smoked_gla1", 3, &table);
    hash_table_set("Metallic_Varni0", 4, &table);
    hash_table_set("Body0", 5, &table);
    hash_table_set("Pottery_clay2", 6, &table);
    hash_table_set("850matri0", 7, &table);
    hash_table_set("850matri1", 8, &table);
    hash_table_set("Pottery_clay3", 9, &table);
    hash_table_set("Pottery_clay4", 10, &table);

    TEST_CHECK(table.capacity > 10);
    TEST_CHECK(table.n == 11);

    TEST_CHECK(hash_table_get("Pottery_clay0", &table) == 0);
    TEST_CHECK(hash_table_get("Dark_smoked_gla0", &table) == 1);
    TEST_CHECK(hash_table_get("Pottery_clay1", &table) == 2);
    TEST_CHECK(hash_table_get("Dark_smoked_gla1", &table) == 3);
    TEST_CHECK(hash_table_get("Metallic_Varni0", &table) == 4);
    TEST_CHECK(hash_table_get("Body0", &table) == 5);
    TEST_CHECK(hash_table_get("Pottery_clay2", &table) == 6);
    TEST_CHECK(hash_table_get("850matri0", &table) == 7);
    TEST_CHECK(hash_table_get("850matri1", &table) == 8);
    TEST_CHECK(hash_table_get("Pottery_clay3", &table) == 9);
    TEST_CHECK(hash_table_get("Pottery_clay4", &table) == 10);

    destroy_hash_table(&table);
}
Пример #11
0
void test_hash_table_set(void)
{
    {
        // Values should be stored in the hash table.
        hash_table_t table;
        int foundFirst = 0;
        int foundSecond = 0;
        int foundOther = 0;
        int i;

        create_hash_table(20, &table);

        TEST_CHECK(table.hashes != NULL);
        TEST_CHECK(table.entries != NULL);
        TEST_CHECK(table.capacity == 20);
        TEST_CHECK(table.n == 0);

        hash_table_set("potato", 3, &table);
        hash_table_set("monkey", 8, &table);

        TEST_CHECK(table.n == 2);

        for (i = 0; i < table.capacity; ++i) {
            hash_table_entry_t n = table.entries[i];
            if (n.value == 3) {
                foundFirst++;
            } else if (n.value == 8) {
                foundSecond++;
            } else {
                foundOther++;
            }
        }

        TEST_CHECK(foundFirst == 1);
        TEST_CHECK(foundSecond == 1);
        TEST_CHECK(foundOther == 18);

        destroy_hash_table(&table);
    }

    {
        // Values with different hashes but same % capacity value should exist in the
        // the same hash table.
        hash_table_t table;
        int foundFirst = 0;
        int foundSecond = 0;
        int foundOther = 0;
        int i;

        create_hash_table(20, &table);

        TEST_CHECK(table.hashes != NULL);
        TEST_CHECK(table.entries != NULL);
        TEST_CHECK(table.capacity == 20);
        TEST_CHECK(table.n == 0);

        // hashes are different but % 20 value is the same - they will end up in the same bucket
        hash_table_set("potato", 3, &table); // hash 356168476
        hash_table_set("potat[", 3, &table); // hash 356168456

        // hashes are different but % 20 value is the same - they will end up in the same bucket
        hash_table_set("monkey", 8, &table); // hash 238557080
        hash_table_set("monkee", 8, &table); // hash 238557060

        TEST_CHECK(table.n == 4);

        for (i = 0; i < table.capacity; ++i) {
            if ((table.entries + i)->value == 3) {
                foundFirst++;
            } else if ((table.entries + i)->value == 8) {
                foundSecond++;
            } else {
                foundOther++;
            }
        }

        TEST_CHECK(foundFirst == 2);
        TEST_CHECK(foundSecond == 2);
        TEST_CHECK(foundOther == 16);

        destroy_hash_table(&table);
    }

    {
        // TODO: This fails. Should the key also be stored in the entry so it can be compared
        // with the key being inserted?
        // Values with identical hashes but different keys should exist in the same hash table.
        hash_table_t table;
        int foundFirst = 0;
        int foundSecond = 0;
        int foundOther = 0;
        int i;

        create_hash_table(20, &table);

        TEST_CHECK(table.hashes != NULL);
        TEST_CHECK(table.entries != NULL);
        TEST_CHECK(table.capacity == 20);
        TEST_CHECK(table.n == 0);

        hash_table_set("potato", 3, &table); // hash 356168476
        hash_table_set("potbSo", 3, &table); // hash 356168476 (identical)

        hash_table_set("monkey", 8, &table); // hash 238557080
        hash_table_set("monkfX", 8, &table); // hash 238557080 (identical)

        // TEST_CHECK(table.n == 4);

        for (i = 0; i < table.capacity; ++i) {
            hash_table_entry_t n = table.entries[i];
            if (n.value == 3) {
                foundFirst++;
            } else if (n.value == 8) {
                foundSecond++;
            } else {
                foundOther++;
            }
        }

        // TEST_CHECK(foundFirst == 2);
        // TEST_CHECK(foundSecond == 2);
        // TEST_CHECK(foundOther == 16);

        destroy_hash_table(&table);
    }
}
Пример #12
0
// Pseduo Unit Tests
int main(){
	hash_table * t = hash_table_new();

	// Does the hash function work correctly?
	printf("Testing Hash Function:\n");
	printf("----------------------\n");
	char test [5]	= {1,2,3,4,'\0'}; // these two keys collide with the default constants 
	char test2 [5]	= {4,8,5,4,'\0'}; // we will use this property later
	printf("hash: %d\n",hash(t,test));
	printf("hash: %d\n",hash(t,test2));
	printf("%s\n\n",(hash(t,test) == (((1 + 2 + 3 + 4) * MULTIPLY_PRIME ) % 11 )) ? "passed" : "failed");

	// Does the set function set and the get function get when there are no collisions?
	printf("Testing Set/Get Functions(no collision):\n");
	printf("----------------------------------------\n");
	int item = 12358;
	hash_table_set(t,test,&item);	
	printf("item = %d\n",(*(int *)hash_table_get(t,test)));
	printf("%s\n\n",(hash_table_get(t,test) == &item) ? "passed" : "failed");
	
	// Does the set function set and the get function get when there is a collision?
	printf("Testing Set/Get Functions(with collision):\n");
	printf("------------------------------------------\n");
	int item2 = 55555;
	hash_table_set(t,test2,&item2);	
	printf("%d\n",(*(int *)hash_table_get(t,test))); // get the original item, which will be down the chain
	printf("%d\n",(*(int *)hash_table_get(t,test2))); // get the second item, which will be on top
	printf("%s\n\n",(hash_table_get(t,test2) == &item2) ? "passed" : "failed");

	// Has the hash table been resized?
	printf("Testing whether the hash table has been resized:\n");
	printf("------------------------------------------\n");
	printf("hash: %d\n",hash(t,test));
	printf("hash: %d\n",hash(t,test2));
	printf("If so, these values should not be equal to the earlier hash values\n");
	printf("As a bonus, they will no longer collide, which is why the expansion was necessary in the first place\n\n");

	// Does get return NULL if nothing set?
	printf("Testing Get Failure:\n");
	printf("--------------------\n");
	printf("%x\n",hash_table_get(t,"abcdefgh"));
	printf("%s\n\n",(hash_table_get(t,"abcdefgh") == NULL) ? "passed" : "failed");



	// Some fun stuff
	hash_table * h = hash_table_new();

	char name[] = "Fake";
	hash_table_set(h,"first_name",&name);
	char last[] = "Person";
	hash_table_set(h,"last_name",&last);
	int age = 100;
	hash_table_set(h,"age",&age);

	printf("My full name is %s %s. I am %d years old\n",(char *)hash_table_get(h,"first_name"), (char *)hash_table_get(h,"last_name"),*((int*)hash_table_get(h,"age")));

	hash_table_delete(t);
	hash_table_delete(h);

}
Пример #13
0
static void populate(Hash_table *table)
{
    hash_table_set(table, "negative one", -1, NULL);
    hash_table_set(table, "zero", 0, NULL);
    hash_table_set(table, "one", 1, NULL);
    hash_table_set(table, "two", 2, NULL);
    hash_table_set(table, "three", 3, NULL);
    hash_table_set(table, "four", 4, NULL);
    hash_table_set(table, "five", 5, NULL);
    hash_table_set(table, "six", 6, NULL);
    hash_table_set(table, "seven", 7, NULL);
    hash_table_set(table, "eight", 8, NULL);
    hash_table_set(table, "nine", 9, NULL);
    hash_table_set(table, "ten", 10, NULL);
    hash_table_set(table, "", 123, NULL);
}