ambrop7 15 лет назад
Родитель
Сommit
239bd17f63
4 измененных файлов с 0 добавлено и 512 удалено
  1. 0 6
      examples/CMakeLists.txt
  2. 0 119
      examples/hashtable_bench.c
  3. 0 94
      examples/hashtable_example.c
  4. 0 293
      structure/HashTable.h

+ 0 - 6
examples/CMakeLists.txt

@@ -1,8 +1,5 @@
 add_executable(linkedlist2_example linkedlist2_example.c)
 
-add_executable(hashtable_example hashtable_example.c)
-target_link_libraries(hashtable_example system)
-
 add_executable(btimer_example btimer_example.c)
 target_link_libraries(btimer_example system)
 
@@ -21,9 +18,6 @@ target_link_libraries(bheap_test security)
 add_executable(bavl_test bavl_test.c)
 target_link_libraries(bavl_test security)
 
-add_executable(hashtable_bench hashtable_bench.c)
-target_link_libraries(hashtable_bench system security)
-
 add_executable(bencryption_bench bencryption_bench.c)
 target_link_libraries(bencryption_bench system security)
 

+ 0 - 119
examples/hashtable_bench.c

@@ -1,119 +0,0 @@
-/**
- * @file hashtable_bench.c
- * @author Ambroz Bizjak <ambrop7@gmail.com>
- * 
- * @section LICENSE
- * 
- * This file is part of BadVPN.
- * 
- * BadVPN is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- * 
- * BadVPN is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdlib.h>
-
-#include <misc/offset.h>
-#include <misc/debug.h>
-#include <misc/jenkins_hash.h>
-#include <structure/HashTable.h>
-#include <security/BRandom.h>
-
-struct mynode {
-    int used;
-    int num;
-    HashTableNode hash_node;
-};
-
-static int key_comparator (int *key1, int *key2)
-{
-    return (*key1 == *key2);
-}
-
-static int hash_function (int *key, int modulo)
-{
-    return (jenkins_one_at_a_time_hash((uint8_t *)key, sizeof(int)) % modulo);
-}
-
-static void print_indent (int indent)
-{
-    for (int i = 0; i < indent; i++) {
-        printf("  ");
-    }
-}
-
-int main (int argc, char **argv)
-{
-    int num_nodes;
-    int num_random_delete;
-    
-    if (argc != 3 || (num_nodes = atoi(argv[1])) <= 0 || (num_random_delete = atoi(argv[2])) < 0) {
-        fprintf(stderr, "Usage: %s <num> <numrandomdelete>\n", (argc > 0 ? argv[0] : NULL));
-        return 1;
-    }
-    
-    struct mynode *nodes = malloc(num_nodes * sizeof(*nodes));
-    if (!nodes) {
-        fprintf(stderr, "malloc failed\n");
-        return 1;
-    }
-    
-    int *values_ins = malloc(num_nodes * sizeof(int));
-    ASSERT_FORCE(values_ins)
-    
-    int *values = malloc(num_random_delete * sizeof(int));
-    ASSERT_FORCE(values)
-    
-    HashTable ht;
-    if (!HashTable_Init(
-        &ht,
-        OFFSET_DIFF(struct mynode, num, hash_node),
-        (HashTable_comparator)key_comparator,
-        (HashTable_hash_function)hash_function,
-        num_nodes * 2
-    )) {
-        fprintf(stderr, "HashTable_Init failed\n");
-        return 1;
-    }
-    
-    printf("Inserting random values...\n");
-    BRandom_randomize((uint8_t *)values_ins, num_nodes * sizeof(int));
-    for (int i = 0; i < num_nodes; i++) {
-        nodes[i].num = values_ins[i];
-        if (HashTable_Insert(&ht, &nodes[i].hash_node)) {
-            nodes[i].used = 1;
-        } else {
-            nodes[i].used = 0;
-            printf("Insert collision!\n");
-        }
-    }
-    
-    printf("Removing random entries...\n");
-    int removed = 0;
-    BRandom_randomize((uint8_t *)values, num_random_delete * sizeof(int));
-    for (int i = 0; i < num_random_delete; i++) {
-        int index = (((unsigned int *)values)[i] % num_nodes);
-        struct mynode *node = nodes + index;
-        if (node->used) {
-            ASSERT_EXECUTE(HashTable_Remove(&ht, &node->num))
-            node->used = 0;
-            removed++;
-        }
-    }
-    
-    printf("Removed %d entries\n", removed);
-    
-    free(nodes);
-    free(values);
-    
-    return 0;
-}

+ 0 - 94
examples/hashtable_example.c

@@ -1,94 +0,0 @@
-/**
- * @file hashtable_example.c
- * @author Ambroz Bizjak <ambrop7@gmail.com>
- * 
- * @section LICENSE
- * 
- * This file is part of BadVPN.
- * 
- * BadVPN is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- * 
- * BadVPN is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stddef.h>
-
-#include <misc/debug.h>
-#include <misc/jenkins_hash.h>
-#include <structure/HashTable.h>
-
-int key_comparator (int *key1, int *key2)
-{
-    return (*key1 == *key2);
-}
-
-int hash_function (int *key, int modulo)
-{
-    return (jenkins_one_at_a_time_hash((uint8_t *)key, sizeof(int)) % modulo);
-}
-
-struct entry {
-    HashTableNode node;
-    int value;
-};
-
-int main ()
-{
-    HashTable table;
-    if (HashTable_Init(
-        &table,
-        (offsetof(struct entry, value) - offsetof(struct entry, node)),
-        (HashTable_comparator)key_comparator,
-        (HashTable_hash_function)hash_function,
-        20
-    ) != 1) {
-        return 1;
-    }
-    
-    struct entry entries[10];
-    
-    // insert entries
-    int i;
-    for (i=0; i<10; i++) {
-        struct entry *entry = &entries[i];
-        // must initialize value before inserting
-        entry->value = i;
-        // insert
-        int res = HashTable_Insert(&table, &entry->node);
-        ASSERT(res == 1)
-    }
-    
-    // lookup entries
-    for (i=0; i<10; i++) {
-        HashTableNode *node;
-        int res = HashTable_Lookup(&table, &i, &node);
-        ASSERT(res == 1)
-        struct entry *entry = (struct entry *)((uint8_t *)node - offsetof(struct entry, node));
-        ASSERT(entry == &entries[i])
-    }
-    
-    // remove entries
-    for (i=0; i<10; i++) {
-        int res = HashTable_Remove(&table, &i);
-        ASSERT(res == 1)
-    }
-    
-    // remove entries again
-    for (i=0; i<10; i++) {
-        int res = HashTable_Remove(&table, &i);
-        ASSERT(res == 0)
-    }
-    
-    HashTable_Free(&table);
-    
-    return 0;
-}

+ 0 - 293
structure/HashTable.h

@@ -1,293 +0,0 @@
-/**
- * @file HashTable.h
- * @author Ambroz Bizjak <ambrop7@gmail.com>
- * 
- * @section LICENSE
- * 
- * This file is part of BadVPN.
- * 
- * BadVPN is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- * 
- * BadVPN is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- * 
- * @section DESCRIPTION
- * 
- * Hash table using separate chaining.
- */
-
-#ifndef BADVPN_STRUCTURE_HASHTABLE_H
-#define BADVPN_STRUCTURE_HASHTABLE_H
-
-#include <stdint.h>
-#include <stddef.h>
-
-#include <misc/debug.h>
-#include <system/DebugObject.h>
-
-/**
- * Handler function used to compare values.
- * For any two values, the comparator must always return the same result.
- * Values are obtained like that:
- *   - The value of a node in the table, or a node that is being inserted is:
- *     (uint8_t *)node + offset.
- *   - The value being looked up is the same as given to the lookup function.
- *
- * @param val1 first value
- * @param val2 second value
- * @return 1 if values are equal, 0 if not
- */
-typedef int (*HashTable_comparator) (void *val1, void *val2);
-
-/**
- * Handler function used to compute the hash of a value, modulo some number.
- * The value is obtained the same way as in {@link HashTable_comparator}.
- *
- * @param val value whose hash function is to be computed
- * @param modulo an integer modulo which the hash must be taken before returning it
- * @return hash of value modulo parameter
- */
-typedef int (*HashTable_hash_function) (void *val, int modulo);
-
-struct HashTableNode_t;
-
-/**
- * Hash table using separate chaining.
- */
-typedef struct {
-    DebugObject d_obj;
-    int offset;
-    HashTable_comparator comparator;
-    HashTable_hash_function hash_function;
-    int num_buckets;
-    struct HashTableNode_t **buckets;
-    #ifndef NDEBUG
-    int in_handler;
-    #endif
-} HashTable;
-
-/**
- * Hash table node.
- */
-typedef struct HashTableNode_t {
-    struct HashTableNode_t *next;
-} HashTableNode;
-
-/**
- * Initializes the hash table.
- *
- * @param t the object
- * @param offset offset of a value from its node
- * @param comparator value comparator handler function
- * @param hash_function value hash function handler function
- * @param size number of buckets in the hash table. Must be >0.
- * @return 1 on success, 0 on failure
- */
-static int HashTable_Init (HashTable *t, int offset, HashTable_comparator comparator, HashTable_hash_function hash_function, int size) WARN_UNUSED;
-
-/**
- * Frees the hash table.
- * Must not be called from handler functions.
- *
- * @param t the object
- */
-static void HashTable_Free (HashTable *t);
-
-/**
- * Inserts a node into the hash table.
- * Must not be called from handler functions.
- *
- * @param t the object
- * @param node uninitialized node to insert. Must have a valid value (its value
- *             may be passed to the comparator or hash function during insertion).
- * @return 1 on success, 0 if an element with an equal value is already in the table
- */
-static int HashTable_Insert (HashTable *t, HashTableNode *node);
-
-/**
- * Removes a node from the table by value.
- * The node must be in the hash table.
- * Must not be called from handler functions.
- *
- * @param t the object
- * @param val value of the node to be removed.
- * @return 1 on success, 0 if there is no node with the given value
- */
-static int HashTable_Remove (HashTable *t, void *val);
-
-/**
- * Looks up the node of the value given.
- * Must not be called from handler functions.
- *
- * @param t the object
- * @param val value to look up
- * @param node if not NULL, will be set to the node pointer on success
- * @return 1 on success, 0 if there is no node with the given value
- */
-static int HashTable_Lookup (HashTable *t, void *val, HashTableNode **node);
-
-static int _HashTable_compare_values (HashTable *t, void *v1, void *v2)
-{
-    #ifndef NDEBUG
-    t->in_handler = 1;
-    #endif
-    
-    int res = t->comparator(v1, v2);
-    
-    #ifndef NDEBUG
-    t->in_handler = 0;
-    #endif
-    
-    ASSERT(res == 0 || res == 1)
-    
-    return res;
-}
-
-static int _HashTable_compute_hash (HashTable *t, void *v)
-{
-    #ifndef NDEBUG
-    t->in_handler = 1;
-    #endif
-    
-    int res = t->hash_function(v, t->num_buckets);
-    
-    #ifndef NDEBUG
-    t->in_handler = 0;
-    #endif
-    
-    ASSERT(res >= 0)
-    ASSERT(res < t->num_buckets)
-    
-    return res;
-}
-
-int HashTable_Init (HashTable *t, int offset, HashTable_comparator comparator, HashTable_hash_function hash_function, int size)
-{
-    ASSERT(size > 0)
-    
-    // init arguments
-    t->offset = offset;
-    t->comparator = comparator;
-    t->hash_function = hash_function;
-    t->num_buckets = size;
-    
-    // allocate buckets
-    t->buckets = (HashTableNode **)malloc(t->num_buckets * sizeof(HashTableNode *));
-    if (!t->buckets) {
-        return 0;
-    }
-    
-    // zero buckets
-    int i;
-    for (i = 0; i < t->num_buckets; i++) {
-        t->buckets[i] = NULL;
-    }
-    
-    // init debugging
-    #ifndef NDEBUG
-    t->in_handler = 0;
-    #endif
-    
-    // init debug object
-    DebugObject_Init(&t->d_obj);
-    
-    return 1;
-}
-
-void HashTable_Free (HashTable *t)
-{
-    // free debug object
-    DebugObject_Free(&t->d_obj);
-    
-    ASSERT(!t->in_handler)
-    
-    // free buckets
-    free(t->buckets);
-}
-
-int HashTable_Insert (HashTable *t, HashTableNode *node)
-{
-    ASSERT(!t->in_handler)
-    
-    // obtain value
-    void *val = (uint8_t *)node + t->offset;
-    
-    // obtain bucket index
-    int index = _HashTable_compute_hash(t, val);
-    
-    // look for existing entries with an equal value
-    HashTableNode *cur = t->buckets[index];
-    while (cur) {
-        void *cur_val = (uint8_t *)cur + t->offset;
-        if (_HashTable_compare_values(t, cur_val, val)) {
-            return 0;
-        }
-        cur = cur->next;
-    }
-    
-    // prepend to linked list
-    node->next = t->buckets[index];
-    t->buckets[index] = node;
-    
-    return 1;
-}
-
-int HashTable_Remove (HashTable *t, void *val)
-{
-    ASSERT(!t->in_handler)
-    
-    // obtain bucket index
-    int index = _HashTable_compute_hash(t, val);
-    
-    // find node with an equal value
-    HashTableNode *prev = NULL;
-    HashTableNode *cur = t->buckets[index];
-    while (cur) {
-        void *cur_val = (uint8_t *)cur + t->offset;
-        if (_HashTable_compare_values(t, cur_val, val)) {
-            // remove node from lined list
-            if (prev) {
-                prev->next = cur->next;
-            } else {
-                t->buckets[index] = cur->next;
-            }
-            return 1;
-        }
-        prev = cur;
-        cur = cur->next;
-    }
-    
-    return 0;
-}
-
-int HashTable_Lookup (HashTable *t, void *val, HashTableNode **node)
-{
-    ASSERT(!t->in_handler)
-    
-    int index = _HashTable_compute_hash(t, val);
-    
-    // find node with an equal value
-    HashTableNode *cur = t->buckets[index];
-    while (cur) {
-        void *cur_val = (uint8_t *)cur + t->offset;
-        if (_HashTable_compare_values(t, cur_val, val)) {
-            if (node) {
-                *node = cur;
-            }
-            return 1;
-        }
-        cur = cur->next;
-    }
-    
-    return 0;
-}
-
-#endif