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


Ignore:
Timestamp:
2025-04-07T17:53:53Z (11 days ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
0c6fc7a, 45226285, 93de384
Parents:
8f8818ac
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-07 16:41:57)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-07 17:53:53)
Message:

Hash table improvements

Implement hash_table_foreach macro, analogous to list_foreach.

Remove superfluous argument to hash_table_find_next().
(If the user needs to recheck the part of the list already
checked by hash_table_find(), they can just rerun that function.)

Add hash argument to hash_table_ops_t::key_equal.
The big change here is that users with big keys can store the hash
value alongside key in their entries, and for the low low cost of
sizeof(size_t) bytes eliminate a bunch of expensive key comparisons.

Also added a hash function for strings and arbitrary data.
Found this one by asking ChatGPT, because the latency of accesses
to my book collection is currently a couple of hours.

+ Some drive-by unused #include removal.

File:
1 edited

Legend:

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

    r8f8818ac r0db0df2  
    5252typedef struct nic_addr_entry {
    5353        ht_link_t link;
     54        size_t hash;
    5455        uint8_t len;
    55         uint8_t addr[1];
     56        uint8_t addr[];
    5657} nic_addr_entry_t;
    5758
     
    6061 */
    6162typedef struct {
     63        size_t hash;
    6264        size_t len;
    6365        const uint8_t *addr;
    6466} addr_key_t;
    6567
    66 static bool nic_addr_key_equal(const void *key_arg, const ht_link_t *item)
     68static bool nic_addr_key_equal(const void *key_arg, size_t hash, const ht_link_t *item)
    6769{
    6870        const addr_key_t *key = key_arg;
    6971        nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
    70 
    71         return memcmp(entry->addr, key->addr, entry->len) == 0;
     72        return entry->hash == hash && memcmp(entry->addr, key->addr, entry->len) == 0;
    7273}
    7374
     
    8687{
    8788        const addr_key_t *key = k;
    88         return addr_hash(key->len, key->addr);
     89        return key->hash ? key->hash : addr_hash(key->len, key->addr);
    8990}
    9091
     
    9293{
    9394        nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
    94         return addr_hash(entry->len, entry->addr);
     95        return entry->hash;
    9596}
    9697
     
    9899{
    99100        nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
    100 
    101101        free(entry);
    102102}
     
    173173        addr_key_t key = {
    174174                .len = db->addr_len,
    175                 .addr = addr
     175                .addr = addr,
     176                .hash = addr_hash(db->addr_len, addr),
    176177        };
    177178
     
    179180                return EEXIST;
    180181
    181         nic_addr_entry_t *entry = malloc(sizeof(nic_addr_entry_t) + db->addr_len - 1);
     182        nic_addr_entry_t *entry = malloc(offsetof(nic_addr_entry_t, addr) + db->addr_len);
    182183        if (entry == NULL)
    183184                return ENOMEM;
     
    185186        entry->len = (uint8_t) db->addr_len;
    186187        memcpy(entry->addr, addr, db->addr_len);
     188        entry->hash = key.hash;
    187189
    188190        hash_table_insert(&db->set, &entry->link);
Note: See TracChangeset for help on using the changeset viewer.