Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/udf/udf_idx.c

    r38fc00b r48e3190  
    4242#include <malloc.h>
    4343#include <adt/hash_table.h>
    44 #include <adt/hash.h>
    4544#include <adt/list.h>
    46 #include <bool.h>
    4745#include "udf_idx.h"
    4846#include "udf.h"
    4947
     48#define UDF_IDX_KEYS  2
     49#define UDF_IDX_KEY   1
     50
     51#define UDF_IDX_SERVICE_ID_KEY  0
     52#define UDF_IDX_BUCKETS         1024
     53
    5054static FIBRIL_MUTEX_INITIALIZE(udf_idx_lock);
    5155
    5256static hash_table_t udf_idx;
    5357
    54 typedef struct {
    55         service_id_t service_id;
    56         fs_index_t index;
    57 } udf_ht_key_t;
    58 
    59 static size_t udf_idx_hash(const ht_link_t *item)
    60 {
    61         udf_node_t *node = hash_table_get_inst(item, udf_node_t, link);
    62         return hash_combine(node->instance->service_id, node->index);
    63 }
    64 
    65 static size_t udf_idx_key_hash(void *k)
    66 {
    67         udf_ht_key_t *key = (udf_ht_key_t *) k;
    68         return hash_combine(key->service_id, key->index);
    69 }
    70 
    71 static bool udf_idx_key_equal(void *k, const ht_link_t *item)
    72 {
    73         udf_ht_key_t *key = (udf_ht_key_t *) k;
    74         udf_node_t *node = hash_table_get_inst(item, udf_node_t, link);
    75 
    76         return (key->service_id == node->instance->service_id) &&
    77             (key->index == node->index);
    78 }
    79 
    80 static hash_table_ops_t udf_idx_ops = {
     58/** Calculate value of hash by key
     59 *
     60 * @param Key for calculation of function
     61 *
     62 * @return Value of hash function
     63 *
     64 */
     65static hash_index_t udf_idx_hash(unsigned long key[])
     66{
     67        /* TODO: This is very simple and probably can be improved */
     68        return key[UDF_IDX_KEY] % UDF_IDX_BUCKETS;
     69}
     70
     71/** Compare two items of hash table
     72 *
     73 * @param key  Key of hash table item. Include several items.
     74 * @param keys Number of parts of key.
     75 * @param item Item of hash table
     76 *
     77 * @return True if input value of key equivalent key of node from hash table
     78 *
     79 */
     80static int udf_idx_compare(unsigned long key[], hash_count_t keys, link_t *item)
     81{
     82        assert(keys > 0);
     83       
     84        udf_node_t *node = hash_table_get_instance(item, udf_node_t, link);
     85       
     86        if (node->instance->service_id !=
     87            ((service_id_t) key[UDF_IDX_SERVICE_ID_KEY]))
     88                return false;
     89       
     90        assert(keys == 2);
     91        return (node->index == key[UDF_IDX_KEY]);
     92}
     93
     94/** Remove callback
     95 *
     96 */
     97static void udf_idx_remove_cb(link_t *link)
     98{
     99        /* We don't use remove callback for this hash table */
     100}
     101
     102static hash_table_operations_t udf_idx_ops = {
    81103        .hash = udf_idx_hash,
    82         .key_hash = udf_idx_key_hash,
    83         .key_equal = udf_idx_key_equal,
    84         .equal = NULL,
    85         .remove_callback = NULL
     104        .compare = udf_idx_compare,
     105        .remove_callback = udf_idx_remove_cb,
    86106};
    87107
     
    93113int udf_idx_init(void)
    94114{
    95         if (!hash_table_create(&udf_idx, 0, 0, &udf_idx_ops))
     115        if (!hash_table_create(&udf_idx, UDF_IDX_BUCKETS, UDF_IDX_KEYS,
     116            &udf_idx_ops))
    96117                return ENOMEM;
    97118       
     
    122143{
    123144        fibril_mutex_lock(&udf_idx_lock);
    124 
    125         udf_ht_key_t key = {
    126                 .service_id = instance->service_id,
    127                 .index = index
     145       
     146        unsigned long key[] = {
     147                [UDF_IDX_SERVICE_ID_KEY] = instance->service_id,
     148                [UDF_IDX_KEY] = index
    128149        };
    129150       
    130         ht_link_t *already_open = hash_table_find(&udf_idx, &key);
     151        link_t *already_open = hash_table_find(&udf_idx, key);
    131152        if (already_open) {
    132                 udf_node_t *node = hash_table_get_inst(already_open,
     153                udf_node_t *node = hash_table_get_instance(already_open,
    133154                    udf_node_t, link);
    134155                node->ref_cnt++;
     
    181202       
    182203        fibril_mutex_initialize(&udf_node->lock);
     204        link_initialize(&udf_node->link);
    183205        fs_node->data = udf_node;
    184206       
    185         hash_table_insert(&udf_idx, &udf_node->link);
     207        unsigned long key[] = {
     208                [UDF_IDX_SERVICE_ID_KEY] = instance->service_id,
     209                [UDF_IDX_KEY] = index
     210        };
     211       
     212        hash_table_insert(&udf_idx, key, &udf_node->link);
    186213        instance->open_nodes_count++;
    187214       
     
    205232        fibril_mutex_lock(&udf_idx_lock);
    206233       
    207         hash_table_remove_item(&udf_idx, &node->link);
     234        unsigned long key[] = {
     235                [UDF_IDX_SERVICE_ID_KEY] = node->instance->service_id,
     236                [UDF_IDX_KEY] = node->index
     237        };
     238       
     239        hash_table_remove(&udf_idx, key, UDF_IDX_KEYS);
    208240       
    209241        assert(node->instance->open_nodes_count > 0);
Note: See TracChangeset for help on using the changeset viewer.