Changeset bc216a0 in mainline for uspace/srv/fs/cdfs/cdfs_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/cdfs/cdfs_ops.c

    rb17518e rbc216a0  
    3737 */
    3838
     39#include "cdfs_ops.h"
    3940#include <bool.h>
    4041#include <adt/hash_table.h>
     42#include <adt/hash.h>
    4143#include <malloc.h>
    4244#include <mem.h>
     
    5052#include "cdfs.h"
    5153#include "cdfs_endian.h"
    52 #include "cdfs_ops.h"
    5354
    5455/** Standard CD-ROM block size */
    5556#define BLOCK_SIZE  2048
    5657
    57 /** Implicit node cache size
    58  *
    59  * More nodes can be actually cached if the files remain
    60  * opended.
    61  *
    62  */
    63 #define NODE_CACHE_SIZE  200
    64 
    65 #define NODES_KEY_SRVC   0
    66 #define NODES_KEY_INDEX  1
     58#define NODE_CACHE_SIZE 200
    6759
    6860/** All root nodes have index 0 */
     
    203195        service_id_t service_id;  /**< Service ID of block device */
    204196       
    205         link_t nh_link;           /**< Nodes hash table link */
     197        ht_link_t nh_link;        /**< Nodes hash table link */
    206198        cdfs_dentry_type_t type;  /**< Dentry type */
    207199       
     
    224216static hash_table_t nodes;
    225217
    226 static size_t nodes_key_hash(unsigned long key[])
    227 {
    228         return key[NODES_KEY_INDEX];
    229 }
    230 
    231 static size_t nodes_hash(const link_t *item)
    232 {
    233         cdfs_node_t *node = hash_table_get_instance(item, cdfs_node_t, nh_link);
    234        
    235         unsigned long key[] = {
    236                 [NODES_KEY_INDEX] = node->index
    237         };
    238        
    239         return nodes_key_hash(key);
    240 }
    241 
    242 static bool nodes_match(unsigned long key[], size_t keys, const link_t *item)
    243 {
    244         cdfs_node_t *node = hash_table_get_instance(item, cdfs_node_t, nh_link);
    245        
    246         if (keys == 1) {
    247                 return (node->service_id == key[NODES_KEY_SRVC]);
    248         } else {
    249                 assert(keys == 2);
    250                 return ((node->service_id == key[NODES_KEY_SRVC]) &&
    251                     (node->index == key[NODES_KEY_INDEX]));
    252         }
    253 }
    254 
    255 static bool nodes_equal(const link_t *item1, const link_t *item2)
    256 {
    257         cdfs_node_t *node1 = hash_table_get_instance(item1, cdfs_node_t, nh_link);
    258         cdfs_node_t *node2 = hash_table_get_instance(item2, cdfs_node_t, nh_link);
    259        
    260         return node1->service_id == node2->service_id
    261                 && node1->index == node2->index;
    262 }
    263 
    264 static void nodes_remove_callback(link_t *item)
    265 {
    266         cdfs_node_t *node = hash_table_get_instance(item, cdfs_node_t, nh_link);
     218/*
     219 * Hash table support functions.
     220 */
     221
     222typedef struct {
     223        service_id_t service_id;
     224    fs_index_t index;
     225} ht_key_t;
     226
     227static size_t nodes_key_hash(void *k)
     228{
     229        ht_key_t *key = (ht_key_t*)k;
     230        return hash_combine(key->service_id, key->index);
     231}
     232
     233static size_t nodes_hash(const ht_link_t *item)
     234{
     235        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
     236        return hash_combine(node->service_id, node->index);
     237}
     238
     239static bool nodes_key_equal(void *k, const ht_link_t *item)
     240{
     241        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
     242        ht_key_t *key = (ht_key_t*)k;
     243       
     244        return key->service_id == node->service_id && key->index == node->index;
     245}
     246
     247static void nodes_remove_callback(ht_link_t *item)
     248{
     249        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
    267250       
    268251        assert(node->type == CDFS_DIRECTORY);
     
    283266        .hash = nodes_hash,
    284267        .key_hash = nodes_key_hash,
    285         .match = nodes_match,
    286         .equal = nodes_equal,
     268        .key_equal = nodes_key_equal,
     269        .equal = 0,
    287270        .remove_callback = nodes_remove_callback
    288271};
     
    291274    fs_index_t index)
    292275{
    293         unsigned long key[] = {
    294                 [NODES_KEY_SRVC] = service_id,
    295                 [NODES_KEY_INDEX] = index
     276        ht_key_t key = {
     277                .index = index,
     278                .service_id = service_id
    296279        };
    297280       
    298         link_t *link = hash_table_find(&nodes, key);
     281        ht_link_t *link = hash_table_find(&nodes, &key);
    299282        if (link) {
    300283                cdfs_node_t *node =
    301                     hash_table_get_instance(link, cdfs_node_t, nh_link);
     284                    hash_table_get_inst(link, cdfs_node_t, nh_link);
    302285               
    303286                *rfn = FS_NODE(node);
     
    325308        node->opened = 0;
    326309       
    327         link_initialize(&node->nh_link);
    328310        list_initialize(&node->cs_list);
    329311}
     
    517499static fs_node_t *get_cached_node(service_id_t service_id, fs_index_t index)
    518500{
    519         unsigned long key[] = {
    520                 [NODES_KEY_SRVC] = service_id,
    521                 [NODES_KEY_INDEX] = index
     501        ht_key_t key = {
     502                .index = index,
     503                .service_id = service_id
    522504        };
    523505       
    524         link_t *link = hash_table_find(&nodes, key);
     506        ht_link_t *link = hash_table_find(&nodes, &key);
    525507        if (link) {
    526508                cdfs_node_t *node =
    527                     hash_table_get_instance(link, cdfs_node_t, nh_link);
     509                    hash_table_get_inst(link, cdfs_node_t, nh_link);
    528510                return FS_NODE(node);
    529511        }
     
    811793}
    812794
     795static bool rm_service_id_nodes(ht_link_t *item, void *arg)
     796{
     797        service_id_t service_id = *(service_id_t*)arg;
     798        cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
     799       
     800        if (node->service_id == service_id) {
     801                hash_table_remove_item(&nodes, &node->nh_link);
     802        }
     803       
     804        return true;
     805}
     806
    813807static void cdfs_instance_done(service_id_t service_id)
    814808{
    815         unsigned long key[] = {
    816                 [NODES_KEY_SRVC] = service_id
    817         };
    818        
    819         hash_table_remove(&nodes, key, 1);
     809        hash_table_apply(&nodes, rm_service_id_nodes, &service_id);
    820810        block_cache_fini(service_id);
    821811        block_fini(service_id);
     
    831821    size_t *rbytes)
    832822{
    833         unsigned long key[] = {
    834                 [NODES_KEY_SRVC] = service_id,
    835                 [NODES_KEY_INDEX] = index
     823        ht_key_t key = {
     824                .index = index,
     825                .service_id = service_id
    836826        };
    837827       
    838         link_t *link = hash_table_find(&nodes, key);
     828        ht_link_t *link = hash_table_find(&nodes, &key);
    839829        if (link == NULL)
    840830                return ENOENT;
    841831       
    842832        cdfs_node_t *node =
    843             hash_table_get_instance(link, cdfs_node_t, nh_link);
     833            hash_table_get_inst(link, cdfs_node_t, nh_link);
    844834       
    845835        if (!node->processed) {
     
    921911}
    922912
    923 static bool cache_remove_closed(link_t *item, void *arg)
     913static bool cache_remove_closed(ht_link_t *item, void *arg)
    924914{
    925915        size_t *premove_cnt = (size_t*)arg;
     
    927917        /* Some nodes were requested to be removed from the cache. */
    928918        if (0 < *premove_cnt) {
    929                 cdfs_node_t *node =     hash_table_get_instance(item, cdfs_node_t, nh_link);
     919                cdfs_node_t *node =     hash_table_get_inst(item, cdfs_node_t, nh_link);
    930920
    931921                if (!node->opened) {
     
    957947                return EOK;
    958948       
    959         unsigned long key[] = {
    960                 [NODES_KEY_SRVC] = service_id,
    961                 [NODES_KEY_INDEX] = index
     949        ht_key_t key = {
     950                .index = index,
     951                .service_id = service_id
    962952        };
    963953       
    964         link_t *link = hash_table_find(&nodes, key);
     954        ht_link_t *link = hash_table_find(&nodes, &key);
    965955        if (link == 0)
    966956                return ENOENT;
    967957       
    968958        cdfs_node_t *node =
    969             hash_table_get_instance(link, cdfs_node_t, nh_link);
     959            hash_table_get_inst(link, cdfs_node_t, nh_link);
    970960       
    971961        assert(node->opened > 0);
     
    10131003bool cdfs_init(void)
    10141004{
    1015         if (!hash_table_create(&nodes, 0, 2, &nodes_ops))
     1005        if (!hash_table_create(&nodes, 0, 0, &nodes_ops))
    10161006                return false;
    10171007       
Note: See TracChangeset for help on using the changeset viewer.