Changeset bc216a0 in mainline for uspace/lib/nic/src/nic_addr_db.c


Ignore:
Timestamp:
2012-08-07T22:13:44Z (12 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
da68871a
Parents:
b17518e
Message:

Refactored any users of hash_table to use opaque void* keys instead of the cumbersome unsigned long[] keys. Switched from the ad hoc computations of hashes of multiple values to hash_combine().

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/nic/src/nic_addr_db.c

    rb17518e rbc216a0  
    3636 */
    3737#include "nic_addr_db.h"
     38#include "libarch/common.h"
    3839#include <assert.h>
    3940#include <stdlib.h>
     
    4344#include <adt/hash_table.h>
    4445#include <macros.h>
    45 
    46 /* The key count hash table field is not used. Use this dummy value. */
    47 #define KEY_CNT 1
    48 
    49 /**
    50  * Maximal length of addresses in the DB (in bytes).
    51  */
    52 #define NIC_ADDR_MAX_LENGTH             16
     46#include <stdint.h>
     47
    5348
    5449/**
     
    5651 */
    5752typedef struct nic_addr_entry {
    58         link_t link;
    59         uint8_t addr[NIC_ADDR_MAX_LENGTH];
     53        ht_link_t link;
     54        uint8_t len;
     55        uint8_t addr[1];
    6056} nic_addr_entry_t;
    6157
     
    6460 * Hash table helper functions
    6561 */
    66 
    67 static bool nic_addr_match(unsigned long *key, size_t key_cnt,
    68         const link_t *item)
    69 {
    70         uint8_t *addr = (uint8_t*)key;
    71         nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
    72 
    73         return 0 == bcmp(entry->addr, addr, NIC_ADDR_MAX_LENGTH);
    74 }
    75 
    76 static size_t nic_addr_key_hash(unsigned long *key)
    77 {
    78         uint8_t *addr = (uint8_t*)key;
     62typedef struct {
     63        size_t len;
     64        const uint8_t *addr;
     65} addr_key_t;
     66
     67static bool nic_addr_key_equal(void *key_arg, const ht_link_t *item)
     68{
     69        addr_key_t *key = (addr_key_t*)key_arg;
     70        nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
     71       
     72        return 0 == bcmp(entry->addr, key->addr, entry->len);
     73}
     74
     75static size_t addr_hash(size_t len, const uint8_t *addr)
     76{
    7977        size_t hash = 0;
    80 
    81         for (int i = NIC_ADDR_MAX_LENGTH - 1; i >= 0; --i) {
    82                 hash = (hash << 8) ^ (hash >> 24) ^ addr[i];
     78       
     79        for (size_t i = 0; i < len; ++i) {
     80                hash = (hash << 5) ^ addr[i];
    8381        }
    8482       
     
    8684}
    8785
    88 static size_t nic_addr_hash(const link_t *item)
    89 {
    90         nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
    91        
    92         unsigned long *key = (unsigned long*)entry->addr;
    93         return nic_addr_key_hash(key);
    94 }
    95 
    96 static void nic_addr_removed(link_t *item)
     86static size_t nic_addr_key_hash(void *k)
     87{
     88        addr_key_t *key = (addr_key_t*)k;
     89        return addr_hash(key->len, key->addr);
     90}
     91
     92static size_t nic_addr_hash(const ht_link_t *item)
     93{
     94        nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
     95        return addr_hash(entry->len, entry->addr);
     96}
     97
     98static void nic_addr_removed(ht_link_t *item)
    9799{
    98100        nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
     
    104106        .hash = nic_addr_hash,
    105107        .key_hash = nic_addr_key_hash,
    106         .match = nic_addr_match,
     108        .key_equal = nic_addr_key_equal,
    107109        .equal = 0,
    108110        .remove_callback = nic_addr_removed
     
    122124{
    123125        assert(db);
    124         if (addr_len > NIC_ADDR_MAX_LENGTH) {
     126       
     127        if (addr_len > UCHAR_MAX)
    125128                return EINVAL;
    126         }
    127        
    128         if (!hash_table_create(&db->set, 0, KEY_CNT, &set_ops))
     129       
     130        if (!hash_table_create(&db->set, 0, 0, &set_ops))
    129131                return ENOMEM;
    130132       
     
    152154{
    153155        assert(db);
    154         nic_addr_db_clear(db);
    155156        hash_table_destroy(&db->set);
    156157}
     
    171172{
    172173        assert(db && addr);
    173         /* Ugly type-punning hack. */
    174         unsigned long *key = (unsigned long*)addr;
    175        
    176         if (hash_table_find(&db->set, key))
     174
     175        addr_key_t key = {
     176                .len = db->addr_len,
     177                .addr = addr
     178        };
     179       
     180        if (hash_table_find(&db->set, &key))
    177181                return EEXIST;
    178182       
    179         nic_addr_entry_t *entry = malloc(sizeof(nic_addr_entry_t));
     183        nic_addr_entry_t *entry = malloc(sizeof(nic_addr_entry_t) + db->addr_len - 1);
    180184        if (entry == NULL)
    181185                return ENOMEM;
    182        
    183         link_initialize(&entry->link);
    184        
    185         bzero(entry->addr, NIC_ADDR_MAX_LENGTH);
     186
     187        entry->len = (uint8_t) db->addr_len;
    186188        memcpy(entry->addr, addr, db->addr_len);
    187189       
     
    202204{
    203205        assert(db && addr);
    204         unsigned long *key = (unsigned long*)addr;
    205        
    206         link_t *item = hash_table_find(&db->set, key);
    207        
    208         if (item) {
    209                 hash_table_remove_item(&db->set, item);
     206       
     207        addr_key_t key = {
     208                .len = db->addr_len,
     209                .addr = addr
     210        };
     211       
     212        if (hash_table_remove(&db->set, &key))
    210213                return EOK;
    211         } else {
     214        else
    212215                return ENOENT;
    213         }
    214216}
    215217
     
    225227{
    226228        assert(db && addr);
    227         unsigned long *key = (unsigned long*)addr;
    228        
    229         return 0 != hash_table_find(&db->set, key);
     229       
     230        addr_key_t key = {
     231                .len = db->addr_len,
     232                .addr = addr
     233        };
     234       
     235        return 0 != hash_table_find(&db->set, &key);
    230236}
    231237
     
    241247 * Helper function for nic_addr_db_foreach
    242248 */
    243 static bool nic_addr_db_fe_helper(link_t *item, void *arg)
     249static bool nic_addr_db_fe_helper(ht_link_t *item, void *arg)
    244250{
    245251        nic_addr_db_fe_arg_t *hs = (nic_addr_db_fe_arg_t *) arg;
Note: See TracChangeset for help on using the changeset viewer.