Changeset bc216a0 in mainline for uspace/srv/fs/ext2fs/ext2fs_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/ext2fs/ext2fs_ops.c

    rb17518e rbc216a0  
    4949#include <byteorder.h>
    5050#include <adt/hash_table.h>
     51#include <adt/hash.h>
    5152#include <adt/list.h>
    5253#include <assert.h>
     
    6263#define EXT2FS_NODE(node)       ((node) ? (ext2fs_node_t *) (node)->data : NULL)
    6364#define EXT2FS_DBG(format, ...) {if (false) printf("ext2fs: %s: " format "\n", __FUNCTION__, ##__VA_ARGS__);}
    64 #define OPEN_NODES_KEYS 2
    65 #define OPEN_NODES_DEV_HANDLE_KEY 0
    66 #define OPEN_NODES_INODE_KEY 1
    6765
    6866typedef struct ext2fs_instance {
     
    7775        ext2_inode_ref_t *inode_ref;
    7876        fs_node_t *fs_node;
    79         link_t link;
     77        ht_link_t link;
    8078        unsigned int references;
    8179} ext2fs_node_t;
     
    121119static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock);
    122120
    123 /* Hash table interface for open nodes hash table */
    124 static size_t open_nodes_key_hash(unsigned long key[])
    125 {
    126         /* Hash construction recommended in Effective Java, 2nd Edition. */
    127         size_t hash = 17;
    128         hash = 31 * hash + key[OPEN_NODES_DEV_HANDLE_KEY];
    129         hash = 31 * hash + key[OPEN_NODES_INODE_KEY];
    130         return hash;
    131 }
    132 
    133 static size_t open_nodes_hash(const link_t *item)
    134 {
    135         ext2fs_node_t *enode = hash_table_get_instance(item, ext2fs_node_t, link);
     121/*
     122 * Hash table interface for open nodes hash table
     123 */
     124
     125typedef struct {
     126        service_id_t service_id;
     127        fs_index_t index;
     128} node_key_t;
     129
     130static size_t open_nodes_key_hash(void *key)
     131{
     132        node_key_t *node_key = (node_key_t*)key;
     133        return hash_combine(node_key->service_id, node_key->index);
     134}
     135
     136static size_t open_nodes_hash(const ht_link_t *item)
     137{
     138        ext2fs_node_t *enode = hash_table_get_inst(item, ext2fs_node_t, link);
    136139
    137140        assert(enode->instance);
    138141        assert(enode->inode_ref);
    139142       
    140         unsigned long key[] = {
    141                 [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id,
    142                 [OPEN_NODES_INODE_KEY] = enode->inode_ref->index,
    143         };
    144        
    145         return open_nodes_key_hash(key);
    146 }
    147 
    148 static bool open_nodes_match(unsigned long key[], size_t keys,
    149     const link_t *item)
    150 {
    151         ext2fs_node_t *enode = hash_table_get_instance(item, ext2fs_node_t, link);
    152         assert(keys > 0);
    153         if (enode->instance->service_id !=
    154             ((service_id_t) key[OPEN_NODES_DEV_HANDLE_KEY])) {
    155                 return false;
    156         }
    157         if (keys == 1) {
    158                 return true;
    159         }
    160         assert(keys == 2);
    161         return (enode->inode_ref->index == key[OPEN_NODES_INODE_KEY]);
     143        return hash_combine(enode->instance->service_id, enode->inode_ref->index);
     144}
     145
     146static bool open_nodes_key_equal(void *key, const ht_link_t *item)
     147{
     148        node_key_t *node_key = (node_key_t*)key;
     149        ext2fs_node_t *enode = hash_table_get_inst(item, ext2fs_node_t, link);
     150       
     151        return node_key->service_id == enode->instance->service_id
     152                && node_key->index == enode->inode_ref->index;
    162153}
    163154
     
    165156        .hash = open_nodes_hash,
    166157        .key_hash = open_nodes_key_hash,
    167         .match = open_nodes_match,
     158        .key_equal = open_nodes_key_equal,
    168159        .equal = 0,
    169160        .remove_callback = 0,
     
    175166int ext2fs_global_init(void)
    176167{
    177         if (!hash_table_create(&open_nodes, 0, OPEN_NODES_KEYS, &open_nodes_ops)) {
     168        if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) {
    178169                return ENOMEM;
    179170        }
     
    329320       
    330321        /* Check if the node is not already open */
    331         unsigned long key[] = {
    332                 [OPEN_NODES_DEV_HANDLE_KEY] = inst->service_id,
    333                 [OPEN_NODES_INODE_KEY] = index,
     322        node_key_t key = {
     323                .service_id = inst->service_id,
     324                .index = index
    334325        };
    335         link_t *already_open = hash_table_find(&open_nodes, key);
     326        ht_link_t *already_open = hash_table_find(&open_nodes, &key);
    336327
    337328        if (already_open) {
    338                 enode = hash_table_get_instance(already_open, ext2fs_node_t, link);
     329                enode = hash_table_get_inst(already_open, ext2fs_node_t, link);
    339330                *rfn = enode->fs_node;
    340331                enode->references++;
     
    370361        enode->references = 1;
    371362        enode->fs_node = node;
    372         link_initialize(&enode->link);
    373363       
    374364        node->data = enode;
     
    421411int ext2fs_node_put_core(ext2fs_node_t *enode)
    422412{
    423         int rc;
    424 
    425         unsigned long key[] = {
    426                 [OPEN_NODES_DEV_HANDLE_KEY] = enode->instance->service_id,
    427                 [OPEN_NODES_INODE_KEY] = enode->inode_ref->index,
     413        node_key_t key = {
     414                .service_id = enode->instance->service_id,
     415                .index = enode->inode_ref->index
    428416        };
    429         hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS);
     417
     418        hash_table_remove(&open_nodes, &key);
     419       
    430420        assert(enode->instance->open_nodes_count > 0);
    431421        enode->instance->open_nodes_count--;
    432422
    433         rc = ext2_filesystem_put_inode_ref(enode->inode_ref);
     423        int rc = ext2_filesystem_put_inode_ref(enode->inode_ref);
    434424        if (rc != EOK) {
    435425                EXT2FS_DBG("ext2_filesystem_put_inode_ref failed");
Note: See TracChangeset for help on using the changeset viewer.