Changeset bc216a0 in mainline for uspace/srv/fs/tmpfs/tmpfs_ops.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/srv/fs/tmpfs/tmpfs_ops.c

    rb17518e rbc216a0  
    5050#include <sys/types.h>
    5151#include <adt/hash_table.h>
     52#include <adt/hash.h>
    5253#include <as.h>
    5354#include <libfs.h>
     
    140141hash_table_t nodes;
    141142
    142 #define NODES_KEY_DEV   0       
    143 #define NODES_KEY_INDEX 1
    144 
    145 /* Implementation of hash table interface for the nodes hash table. */
    146 static size_t nodes_key_hash(unsigned long key[])
    147 {
    148         /* Based on Effective Java, 2nd Edition. */
    149         size_t hash = 17;
    150         hash = 37 * hash + key[NODES_KEY_DEV];
    151         hash = 37 * hash + key[NODES_KEY_INDEX];
    152         return hash;
    153 }
    154 
    155 static size_t nodes_hash(const link_t *item)
    156 {
    157         tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, nh_link);
    158        
    159         unsigned long key[] = {
    160                 [NODES_KEY_DEV] = nodep->service_id,
    161                 [NODES_KEY_INDEX] = nodep->index
    162         };
    163        
    164         return nodes_key_hash(key);
    165 }
    166 
    167 static bool nodes_match(unsigned long key[], size_t keys, const link_t *item)
    168 {
    169         tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
    170             nh_link);
    171        
    172         switch (keys) {
    173         case 1:
    174                 return (nodep->service_id == key[NODES_KEY_DEV]);
    175         case 2:
    176                 return ((nodep->service_id == key[NODES_KEY_DEV]) &&
    177                     (nodep->index == key[NODES_KEY_INDEX]));
    178         default:
    179                 assert((keys == 1) || (keys == 2));
    180         }
    181 
    182         return 0;
    183 }
    184 
    185 static void nodes_remove_callback(link_t *item)
    186 {
    187         tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
    188             nh_link);
     143/*
     144 * Implementation of hash table interface for the nodes hash table.
     145 */
     146
     147typedef struct {
     148        service_id_t service_id;
     149        fs_index_t index;
     150} node_key_t;
     151
     152static size_t nodes_key_hash(void *k)
     153{
     154        node_key_t *key = (node_key_t *)k;
     155        return hash_combine(key->service_id, key->index);
     156}
     157
     158static size_t nodes_hash(const ht_link_t *item)
     159{
     160        tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link);
     161        return hash_combine(nodep->service_id, nodep->index);
     162}
     163
     164static bool nodes_key_equal(void *key_arg, const ht_link_t *item)
     165{
     166        tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link);
     167        node_key_t *key = (node_key_t *)key_arg;
     168       
     169        return key->service_id == node->service_id && key->index == node->index;
     170}
     171
     172static void nodes_remove_callback(ht_link_t *item)
     173{
     174        tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link);
    189175
    190176        while (!list_empty(&nodep->cs_list)) {
     
    209195        .hash = nodes_hash,
    210196        .key_hash = nodes_key_hash,
    211         .match = nodes_match,
     197        .key_equal = nodes_key_equal,
    212198        .equal = 0,
    213199        .remove_callback = nodes_remove_callback
     
    223209        nodep->size = 0;
    224210        nodep->data = NULL;
    225         link_initialize(&nodep->nh_link);
    226211        list_initialize(&nodep->cs_list);
    227212}
     
    236221bool tmpfs_init(void)
    237222{
    238         if (!hash_table_create(&nodes, 0, 2, &nodes_ops))
     223        if (!hash_table_create(&nodes, 0, 0, &nodes_ops))
    239224                return false;
    240225       
     
    254239}
    255240
     241static bool rm_service_id_nodes(ht_link_t *item, void *arg)
     242{
     243        service_id_t sid = *(service_id_t*)arg;
     244        tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link);
     245       
     246        if (node->service_id == sid) {
     247                hash_table_remove_item(&nodes, &node->nh_link);
     248        }
     249        return true;
     250}
     251
    256252static void tmpfs_instance_done(service_id_t service_id)
    257 {
    258         unsigned long key[] = {
    259                 [NODES_KEY_DEV] = service_id
    260         };
    261         /*
    262          * Here we are making use of one special feature of our hash table
    263          * implementation, which allows to remove more items based on a partial
    264          * key match. In the following, we are going to remove all nodes
    265          * matching our device handle. The nodes_remove_callback() function will
    266          * take care of resource deallocation.
    267          */
    268         hash_table_remove(&nodes, key, 1);
     253{       
     254        hash_table_apply(&nodes, rm_service_id_nodes, &service_id);
    269255}
    270256
     
    288274int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
    289275{
    290         unsigned long key[] = {
    291                 [NODES_KEY_DEV] = service_id,
    292                 [NODES_KEY_INDEX] = index
     276        node_key_t key = {
     277                .service_id = service_id,
     278                .index = index
    293279        };
    294         link_t *lnk = hash_table_find(&nodes, key);
     280       
     281        ht_link_t *lnk = hash_table_find(&nodes, &key);
     282       
    295283        if (lnk) {
    296284                tmpfs_node_t *nodep;
    297                 nodep = hash_table_get_instance(lnk, tmpfs_node_t, nh_link);
     285                nodep = hash_table_get_inst(lnk, tmpfs_node_t, nh_link);
    298286                *rfn = FS_NODE(nodep);
    299287        } else {
     
    358346        assert(!nodep->lnkcnt);
    359347        assert(list_empty(&nodep->cs_list));
    360 
    361         unsigned long key[] = {
    362                 [NODES_KEY_DEV] = nodep->service_id,
    363                 [NODES_KEY_INDEX] = nodep->index
    364         };
    365         hash_table_remove(&nodes, key, 2);
     348       
     349        hash_table_remove_item(&nodes, &nodep->nh_link);
    366350
    367351        /*
     
    488472         * Lookup the respective TMPFS node.
    489473         */
    490         link_t *hlp;
    491         unsigned long key[] = {
    492                 [NODES_KEY_DEV] = service_id,
    493                 [NODES_KEY_INDEX] = index
     474        node_key_t key = {
     475                .service_id = service_id,
     476                .index = index
    494477        };
    495         hlp = hash_table_find(&nodes, key);
     478       
     479        ht_link_t *hlp = hash_table_find(&nodes, &key);
    496480        if (!hlp)
    497481                return ENOENT;
    498         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    499             nh_link);
     482       
     483        tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link);
    500484       
    501485        /*
     
    550534         * Lookup the respective TMPFS node.
    551535         */
    552         link_t *hlp;
    553         unsigned long key[] = {
    554                 [NODES_KEY_DEV] = service_id,
    555                 [NODES_KEY_INDEX] = index
     536        node_key_t key = {
     537                .service_id = service_id,
     538                .index = index
    556539        };
    557         hlp = hash_table_find(&nodes, key);
     540       
     541        ht_link_t *hlp = hash_table_find(&nodes, &key);
     542       
    558543        if (!hlp)
    559544                return ENOENT;
    560         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    561             nh_link);
     545       
     546        tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link);
    562547
    563548        /*
     
    612597         * Lookup the respective TMPFS node.
    613598         */
    614         unsigned long key[] = {
    615                 [NODES_KEY_DEV] = service_id,
    616                 [NODES_KEY_INDEX] = index
     599        node_key_t key = {
     600                .service_id = service_id,
     601                .index = index
    617602        };
    618         link_t *hlp = hash_table_find(&nodes, key);
     603       
     604        ht_link_t *hlp = hash_table_find(&nodes, &key);
     605       
    619606        if (!hlp)
    620607                return ENOENT;
    621         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link);
     608        tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link);
    622609       
    623610        if (size == nodep->size)
     
    648635static int tmpfs_destroy(service_id_t service_id, fs_index_t index)
    649636{
    650         link_t *hlp;
    651         unsigned long key[] = {
    652                 [NODES_KEY_DEV] = service_id,
    653                 [NODES_KEY_INDEX] = index
     637        node_key_t key = {
     638                .service_id = service_id,
     639                .index = index
    654640        };
    655         hlp = hash_table_find(&nodes, key);
     641       
     642        ht_link_t *hlp = hash_table_find(&nodes, &key);
    656643        if (!hlp)
    657644                return ENOENT;
    658         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
     645        tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t,
    659646            nh_link);
    660647        return tmpfs_destroy_node(FS_NODE(nodep));
Note: See TracChangeset for help on using the changeset viewer.