Changeset bc216a0 in mainline
- Timestamp:
- 2012-08-07T22:13:44Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- da68871a
- Parents:
- b17518e
- Location:
- uspace
- Files:
-
- 1 added
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/mkexfat/mkexfat.c
rb17518e rbc216a0 49 49 #include <str.h> 50 50 #include <getopt.h> 51 #include <macros.h> 51 52 #include "exfat.h" 52 53 #include "upcase.h" … … 87 88 #define FIRST_FREE_CLUSTER 2 88 89 89 #define min(x, y) ((x) < (y) ? (x) : (y))90 90 91 91 typedef struct exfat_cfg { -
uspace/app/trace/ipcp.c
rb17518e rbc216a0 53 53 ipc_callid_t call_hash; 54 54 55 link_t link;55 ht_link_t link; 56 56 } pending_call_t; 57 57 … … 73 73 proto_t *proto_unknown; /**< Protocol with no known methods. */ 74 74 75 static size_t pending_call_key_hash(unsigned long key[]); 76 static size_t pending_call_hash(const link_t *item); 77 static bool pending_call_match(unsigned long key[], size_t keys, 78 const link_t *item); 75 76 static size_t pending_call_key_hash(void *key) 77 { 78 ipc_callid_t *call_id = (ipc_callid_t *)key; 79 return *call_id; 80 } 81 82 static size_t pending_call_hash(const ht_link_t *item) 83 { 84 pending_call_t *hs = hash_table_get_inst(item, pending_call_t, link); 85 return hs->call_hash; 86 } 87 88 static bool pending_call_key_equal(void *key, const ht_link_t *item) 89 { 90 ipc_callid_t *call_id = (ipc_callid_t *)key; 91 pending_call_t *hs = hash_table_get_inst(item, pending_call_t, link); 92 93 return *call_id == hs->call_hash; 94 } 79 95 80 96 static hash_table_ops_t pending_call_ops = { 81 97 .hash = pending_call_hash, 82 98 .key_hash = pending_call_key_hash, 83 . match = pending_call_match,99 .key_equal = pending_call_key_equal, 84 100 .equal = 0, 85 101 .remove_callback = 0 86 102 }; 87 88 89 static size_t pending_call_key_hash(unsigned long key[])90 {91 size_t hash = 17;92 hash = 31 * hash + key[1];93 hash = 31 * hash + key[0];94 return hash;95 }96 97 static size_t pending_call_hash(const link_t *item)98 {99 pending_call_t *hs = hash_table_get_instance(item, pending_call_t, link);100 unsigned long key[] = {101 LOWER32(hs->call_hash),102 UPPER32(hs->call_hash)103 };104 return pending_call_key_hash(key);105 }106 107 static bool pending_call_match(unsigned long key[], size_t keys,108 const link_t *item)109 {110 assert(keys == 2);111 pending_call_t *hs = hash_table_get_instance(item, pending_call_t, link);112 113 return MERGE_LOUP32(key[0], key[1]) == hs->call_hash;114 }115 116 103 117 104 … … 184 171 } 185 172 186 hash_table_create(&pending_calls, 0, 2, &pending_call_ops); 173 bool ok = hash_table_create(&pending_calls, 0, 0, &pending_call_ops); 174 assert(ok); 187 175 } 188 176 … … 338 326 void ipcp_call_in(ipc_call_t *call, ipc_callid_t hash) 339 327 { 340 link_t *item;328 ht_link_t *item; 341 329 pending_call_t *pcall; 342 330 … … 350 338 351 339 hash = hash & ~IPC_CALLID_ANSWERED; 352 unsigned long key[] = { 353 LOWER32(hash), 354 UPPER32(hash) 355 }; 356 357 item = hash_table_find(&pending_calls, key); 340 341 item = hash_table_find(&pending_calls, &hash); 358 342 if (item == NULL) 359 343 return; /* No matching question found */ … … 363 347 */ 364 348 365 pcall = hash_table_get_inst ance(item, pending_call_t, link);366 hash_table_remove(&pending_calls, key, 2);349 pcall = hash_table_get_inst(item, pending_call_t, link); 350 hash_table_remove(&pending_calls, &hash); 367 351 368 352 parse_answer(hash, pcall, call); -
uspace/app/trace/proto.c
rb17518e rbc216a0 45 45 46 46 typedef struct { 47 unsignedsrv;47 int srv; 48 48 proto_t *proto; 49 link_t link;49 ht_link_t link; 50 50 } srv_proto_t; 51 51 52 52 typedef struct { 53 sysarg_t method;53 int method; 54 54 oper_t *oper; 55 link_t link;55 ht_link_t link; 56 56 } method_oper_t; 57 57 58 59 60 61 static size_t srv_proto_key_hash(unsigned long key[]) 62 { 63 return key[0]; 64 } 65 66 static size_t srv_proto_hash(const link_t *item) 67 { 68 srv_proto_t *sp = hash_table_get_instance(item, srv_proto_t, link); 69 unsigned long key = sp->srv; 70 return srv_proto_key_hash(&key); 71 } 72 73 static bool srv_proto_match(unsigned long key[], size_t keys, const link_t *item) 74 { 75 srv_proto_t *sp = hash_table_get_instance(item, srv_proto_t, link); 76 77 return key[0] == sp->srv; 58 /* Hash table operations. */ 59 60 static size_t srv_proto_key_hash(void *key) 61 { 62 return *(int *)key; 63 } 64 65 static size_t srv_proto_hash(const ht_link_t *item) 66 { 67 srv_proto_t *sp = hash_table_get_inst(item, srv_proto_t, link); 68 return sp->srv; 69 } 70 71 static bool srv_proto_key_equal(void *key, const ht_link_t *item) 72 { 73 srv_proto_t *sp = hash_table_get_inst(item, srv_proto_t, link); 74 return sp->srv == *(int *)key; 78 75 } 79 76 … … 81 78 .hash = srv_proto_hash, 82 79 .key_hash = srv_proto_key_hash, 83 . match = srv_proto_match,80 .key_equal = srv_proto_key_equal, 84 81 .equal = 0, 85 82 .remove_callback = 0 … … 87 84 88 85 89 static size_t method_oper_key_hash(unsigned long key[]) 90 { 91 return key[0]; 92 } 93 94 static size_t method_oper_hash(const link_t *item) 95 { 96 method_oper_t *mo = hash_table_get_instance(item, method_oper_t, link); 97 unsigned long key = mo->method; 98 return method_oper_key_hash(&key); 99 } 100 101 static bool method_oper_match(unsigned long key[], size_t keys, 102 const link_t *item) 103 { 104 method_oper_t *mo = hash_table_get_instance(item, method_oper_t, link); 105 106 return key[0] == mo->method; 86 static size_t method_oper_key_hash(void *key) 87 { 88 return *(int *)key; 89 } 90 91 static size_t method_oper_hash(const ht_link_t *item) 92 { 93 method_oper_t *mo = hash_table_get_inst(item, method_oper_t, link); 94 return mo->method; 95 } 96 97 static bool method_oper_key_equal(void *key, const ht_link_t *item) 98 { 99 method_oper_t *mo = hash_table_get_inst(item, method_oper_t, link); 100 return mo->method == *(int *)key; 107 101 } 108 102 … … 110 104 .hash = method_oper_hash, 111 105 .key_hash = method_oper_key_hash, 112 . match = method_oper_match,106 .key_equal = method_oper_key_equal, 113 107 .equal = 0, 114 108 .remove_callback = 0 … … 118 112 void proto_init(void) 119 113 { 120 hash_table_create(&srv_proto, 0, 1, &srv_proto_ops); 114 /* todo: check return value. */ 115 bool ok = hash_table_create(&srv_proto, 0, 0, &srv_proto_ops); 116 assert(ok); 121 117 } 122 118 … … 139 135 proto_t *proto_get_by_srv(int srv) 140 136 { 141 link_t *item; 142 srv_proto_t *sp; 143 144 unsigned long key = srv; 145 item = hash_table_find(&srv_proto, &key); 137 ht_link_t *item = hash_table_find(&srv_proto, &srv); 146 138 if (item == NULL) return NULL; 147 139 148 s p = hash_table_get_instance(item, srv_proto_t, link);140 srv_proto_t *sp = hash_table_get_inst(item, srv_proto_t, link); 149 141 return sp->proto; 150 142 } … … 153 145 { 154 146 proto->name = name; 155 hash_table_create(&proto->method_oper, 0, 1, &method_oper_ops); 147 /* todo: check return value. */ 148 bool ok = hash_table_create(&proto->method_oper, 0, 0, &method_oper_ops); 149 assert(ok); 156 150 } 157 151 … … 184 178 oper_t *proto_get_oper(proto_t *proto, int method) 185 179 { 186 unsigned long key; 187 link_t *item; 188 method_oper_t *mo; 189 190 key = method; 191 item = hash_table_find(&proto->method_oper, &key); 180 ht_link_t *item = hash_table_find(&proto->method_oper, &method); 192 181 if (item == NULL) return NULL; 193 182 194 m o = hash_table_get_instance(item, method_oper_t, link);183 method_oper_t *mo = hash_table_get_inst(item, method_oper_t, link); 195 184 return mo->oper; 196 185 } -
uspace/lib/block/libblock.c
rb17518e rbc216a0 254 254 } 255 255 256 static size_t cache_key_hash(unsigned long *key) 257 { 258 /* As recommended by Effective Java, 2nd Edition. */ 259 size_t hash = 17; 260 hash = 31 * hash + key[1]; 261 hash = 31 * hash + key[0]; 262 return hash; 263 } 264 265 static size_t cache_hash(const link_t *item) 266 { 267 block_t *b = hash_table_get_instance(item, block_t, hash_link); 268 unsigned long key[] = { 269 LOWER32(b->lba), 270 UPPER32(b->lba) 271 }; 272 273 return cache_key_hash(key); 274 } 275 276 static bool cache_match(unsigned long *key, size_t keys, const link_t *item) 277 { 278 block_t *b = hash_table_get_instance(item, block_t, hash_link); 279 return b->lba == MERGE_LOUP32(key[0], key[1]); 256 static size_t cache_key_hash(void *key) 257 { 258 aoff64_t *lba = (aoff64_t*)key; 259 return *lba; 260 } 261 262 static size_t cache_hash(const ht_link_t *item) 263 { 264 block_t *b = hash_table_get_inst(item, block_t, hash_link); 265 return b->lba; 266 } 267 268 static bool cache_key_equal(void *key, const ht_link_t *item) 269 { 270 aoff64_t *lba = (aoff64_t*)key; 271 block_t *b = hash_table_get_inst(item, block_t, hash_link); 272 return b->lba == *lba; 280 273 } 281 274 … … 284 277 .hash = cache_hash, 285 278 .key_hash = cache_key_hash, 286 . match = cache_match,279 .key_equal = cache_key_equal, 287 280 .equal = 0, 288 281 .remove_callback = 0 … … 317 310 cache->blocks_cluster = cache->lblock_size / devcon->pblock_size; 318 311 319 if (!hash_table_create(&cache->block_hash, 0, 2, &cache_ops)) {312 if (!hash_table_create(&cache->block_hash, 0, 0, &cache_ops)) { 320 313 free(cache); 321 314 return ENOMEM; … … 355 348 } 356 349 357 unsigned long key[2] = { 358 LOWER32(b->lba), 359 UPPER32(b->lba) 360 }; 361 hash_table_remove(&cache->block_hash, key, 2); 350 hash_table_remove_item(&cache->block_hash, &b->hash_link); 362 351 363 352 free(b->data); … … 391 380 fibril_rwlock_initialize(&b->contents_lock); 392 381 link_initialize(&b->free_link); 393 link_initialize(&b->hash_link);394 382 } 395 383 … … 411 399 cache_t *cache; 412 400 block_t *b; 413 link_t *l; 414 unsigned long key[2] = { 415 LOWER32(ba), 416 UPPER32(ba) 417 }; 401 link_t *link; 418 402 419 403 int rc; … … 431 415 432 416 fibril_mutex_lock(&cache->lock); 433 l = hash_table_find(&cache->block_hash, key);434 if ( l) {417 ht_link_t *hlink = hash_table_find(&cache->block_hash, &ba); 418 if (hlink) { 435 419 found: 436 420 /* 437 421 * We found the block in the cache. 438 422 */ 439 b = hash_table_get_inst ance(l, block_t, hash_link);423 b = hash_table_get_inst(hlink, block_t, hash_link); 440 424 fibril_mutex_lock(&b->lock); 441 425 if (b->refcnt++ == 0) … … 475 459 goto out; 476 460 } 477 l = list_first(&cache->free_list);478 b = list_get_instance(l , block_t, free_link);461 link = list_first(&cache->free_list); 462 b = list_get_instance(link, block_t, free_link); 479 463 480 464 fibril_mutex_lock(&b->lock); … … 516 500 goto retry; 517 501 } 518 l = hash_table_find(&cache->block_hash, key);519 if ( l) {502 hlink = hash_table_find(&cache->block_hash, &ba); 503 if (hlink) { 520 504 /* 521 505 * Someone else must have already … … 539 523 */ 540 524 list_remove(&b->free_link); 541 unsigned long temp_key[2] = { 542 LOWER32(b->lba), 543 UPPER32(b->lba) 544 }; 545 hash_table_remove(&cache->block_hash, temp_key, 2); 525 hash_table_remove_item(&cache->block_hash, &b->hash_link); 546 526 } 547 527 … … 663 643 * Take the block out of the cache and free it. 664 644 */ 665 unsigned long key[2] = { 666 LOWER32(block->lba), 667 UPPER32(block->lba) 668 }; 669 hash_table_remove(&cache->block_hash, key, 2); 645 hash_table_remove_item(&cache->block_hash, &block->hash_link); 670 646 fibril_mutex_unlock(&block->lock); 671 647 free(block->data); -
uspace/lib/block/libblock.h
rb17518e rbc216a0 84 84 link_t free_link; 85 85 /** Link for placing the block into the block hash table. */ 86 link_t hash_link;86 ht_link_t hash_link; 87 87 /** Buffer with the block data. */ 88 88 void *data; -
uspace/lib/c/generic/adt/hash_table.c
rb17518e rbc216a0 1 1 /* 2 2 * Copyright (c) 2008 Jakub Jermar 3 * Copyright (c) 2012 Adam Hraska 4 * 3 5 * All rights reserved. 4 6 * … … 62 64 static size_t round_up_size(size_t size); 63 65 static bool alloc_table(size_t bucket_cnt, list_t **pbuckets); 64 static void item_inserted(hash_table_t *h); 65 static void item_removed(hash_table_t *h); 66 static inline void remove_item(hash_table_t *h, link_t *item); 67 static size_t remove_duplicates(hash_table_t *h, unsigned long key[]); 68 static size_t remove_matching(hash_table_t *h, unsigned long key[], size_t key_cnt); 66 static void clear_items(hash_table_t *h); 67 static void resize(hash_table_t *h, size_t new_bucket_cnt); 68 static void grow_if_needed(hash_table_t *h); 69 static void shrink_if_needed(hash_table_t *h); 69 70 70 71 /* Dummy do nothing callback to invoke in place of remove_callback == NULL. */ 71 static void nop_remove_callback( link_t *item)72 static void nop_remove_callback(ht_link_t *item) 72 73 { 73 74 /* no-op */ … … 90 91 * 91 92 */ 92 bool hash_table_create(hash_table_t *h, size_t init_size, size_t max_ keys,93 bool hash_table_create(hash_table_t *h, size_t init_size, size_t max_load, 93 94 hash_table_ops_t *op) 94 95 { 95 96 assert(h); 96 assert(op && op->hash && op->key_hash && op->match); 97 assert(max_keys > 0); 97 assert(op && op->hash && op->key_hash && op->key_equal); 98 99 /* Check for compulsory ops. */ 100 if (!op || !op->hash || !op->key_hash || !op->key_equal) 101 return false; 98 102 99 103 h->bucket_cnt = round_up_size(init_size); … … 102 106 return false; 103 107 104 h->max_ keys = max_keys;105 h->item s= 0;108 h->max_load = (max_load == 0) ? HT_MAX_LOAD : max_load; 109 h->item_cnt = 0; 106 110 h->op = op; 107 108 if (h->op->remove_callback == 0) 111 h->full_item_cnt = h->max_load * h->bucket_cnt; 112 h->apply_ongoing = false; 113 114 if (h->op->remove_callback == 0) { 109 115 h->op->remove_callback = nop_remove_callback; 116 } 110 117 111 118 return true; 112 119 } 113 120 121 /** Destroy a hash table instance. 122 * 123 * @param h Hash table to be destroyed. 124 * 125 */ 126 void hash_table_destroy(hash_table_t *h) 127 { 128 assert(h && h->bucket); 129 assert(!h->apply_ongoing); 130 131 clear_items(h); 132 133 free(h->bucket); 134 135 h->bucket = 0; 136 h->bucket_cnt = 0; 137 } 138 139 /** Returns true if there are no items in the table. */ 140 bool hash_table_empty(hash_table_t *h) 141 { 142 assert(h && h->bucket); 143 return h->item_cnt == 0; 144 } 145 146 /** Returns the number of items in the table. */ 147 size_t hash_table_size(hash_table_t *h) 148 { 149 assert(h && h->bucket); 150 return h->item_cnt; 151 } 152 114 153 /** Remove all elements from the hash table 115 154 * … … 118 157 void hash_table_clear(hash_table_t *h) 119 158 { 159 assert(h && h->bucket); 160 assert(!h->apply_ongoing); 161 162 clear_items(h); 163 164 /* Shrink the table to its minimum size if possible. */ 165 if (HT_MIN_BUCKETS < h->bucket_cnt) { 166 resize(h, HT_MIN_BUCKETS); 167 } 168 } 169 170 /** Unlinks and removes all items but does not resize. */ 171 static void clear_items(hash_table_t *h) 172 { 173 if (h->item_cnt == 0) 174 return; 175 120 176 for (size_t idx = 0; idx < h->bucket_cnt; ++idx) { 121 177 list_foreach_safe(h->bucket[idx], cur, next) { 178 assert(cur); 179 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 180 122 181 list_remove(cur); 123 h->op->remove_callback(cur); 124 } 125 } 126 127 h->items = 0; 128 129 /* Shrink the table to its minimum size if possible. */ 130 if (HT_MIN_BUCKETS < h->bucket_cnt) { 131 list_t *new_buckets; 132 if (alloc_table(HT_MIN_BUCKETS, &new_buckets)) { 133 free(h->bucket); 134 h->bucket = new_buckets; 135 h->bucket_cnt = HT_MIN_BUCKETS; 136 } 137 } 138 } 139 140 /** Destroy a hash table instance. 141 * 142 * @param h Hash table to be destroyed. 143 * 144 */ 145 void hash_table_destroy(hash_table_t *h) 146 { 147 assert(h); 148 assert(h->bucket); 149 150 free(h->bucket); 151 152 h->bucket = 0; 153 h->bucket_cnt = 0; 182 h->op->remove_callback(cur_link); 183 } 184 } 185 186 h->item_cnt = 0; 154 187 } 155 188 … … 160 193 * @param item Item to be inserted into the hash table. 161 194 */ 162 void hash_table_insert(hash_table_t *h, link_t *item)195 void hash_table_insert(hash_table_t *h, ht_link_t *item) 163 196 { 164 197 assert(item); 165 198 assert(h && h->bucket); 166 assert( h->op && h->op->hash);199 assert(!h->apply_ongoing); 167 200 168 201 size_t idx = h->op->hash(item) % h->bucket_cnt; 169 202 170 assert(idx < h->bucket_cnt); 171 172 list_append(item, &h->bucket[idx]); 173 item_inserted(h); 203 list_append(&item->link, &h->bucket[idx]); 204 ++h->item_cnt; 205 grow_if_needed(h); 174 206 } 175 207 … … 184 216 * @return True if the inserted item was the only item with such a lookup key. 185 217 */ 186 bool hash_table_insert_unique(hash_table_t *h, link_t *item)218 bool hash_table_insert_unique(hash_table_t *h, ht_link_t *item) 187 219 { 188 220 assert(item); 189 221 assert(h && h->bucket && h->bucket_cnt); 190 222 assert(h->op && h->op->hash && h->op->equal); 191 192 size_t item_hash = h->op->hash(item); 193 size_t idx = item_hash % h->bucket_cnt; 194 195 assert(idx < h->bucket_cnt); 223 assert(!h->apply_ongoing); 224 225 size_t idx = h->op->hash(item) % h->bucket_cnt; 196 226 197 227 /* Check for duplicates. */ … … 201 231 * calling equal() might very well be just as fast. 202 232 */ 203 if (h->op->equal(cur, item)) 233 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 234 if (h->op->equal(cur_link, item)) 204 235 return false; 205 236 } 206 237 207 list_append(item, &h->bucket[idx]); 208 item_inserted(h); 238 list_append(&item->link, &h->bucket[idx]); 239 ++h->item_cnt; 240 grow_if_needed(h); 209 241 210 242 return true; … … 219 251 * 220 252 */ 221 link_t *hash_table_find(const hash_table_t *h, unsigned long key[]) 222 { 223 assert(h && h->bucket); 224 assert(h->op && h->op->key_hash && h->op->match); 225 226 size_t key_hash = h->op->key_hash(key); 227 size_t idx = key_hash % h->bucket_cnt; 228 229 assert(idx < h->bucket_cnt); 230 253 ht_link_t *hash_table_find(const hash_table_t *h, void *key) 254 { 255 assert(h && h->bucket); 256 257 size_t idx = h->op->key_hash(key) % h->bucket_cnt; 258 231 259 list_foreach(h->bucket[idx], cur) { 260 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 232 261 /* 233 262 * Is this is the item we are looking for? We could have first 234 * checked if the hashes match but op-> match() may very well be263 * checked if the hashes match but op->key_equal() may very well be 235 264 * just as fast as op->hash(). 236 265 */ 237 if (h->op-> match(key, h->max_keys, cur)) {238 return cur ;266 if (h->op->key_equal(key, cur_link)) { 267 return cur_link; 239 268 } 240 269 } … … 243 272 } 244 273 245 246 /** Apply function to all items in hash table. 247 * 248 * @param h Hash table. 249 * @param f Function to be applied. Return false if no more items 250 * should be visited. The functor must not delete the successor 251 * of the item passed in the first argument. 252 * @param arg Argument to be passed to the function. 253 * 254 */ 255 void hash_table_apply(hash_table_t *h, bool (*f)(link_t *, void *), void *arg) 256 { 257 for (size_t idx = 0; idx < h->bucket_cnt; ++idx) { 258 list_foreach_safe(h->bucket[idx], cur, next) { 259 /* 260 * The next pointer had already been saved. f() may safely 261 * delete cur (but not next!). 262 */ 263 if (!f(cur, arg)) 264 return; 265 } 266 } 274 /** Find the next item equal to item. */ 275 ht_link_t *hash_table_find_next(const hash_table_t *h, ht_link_t *item) 276 { 277 assert(item); 278 assert(h && h->bucket); 279 280 /* Traverse the circular list until we reach the starting item again. */ 281 for (link_t *cur = item->link.next; cur != &item->link; cur = cur->next) { 282 assert(cur); 283 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 284 /* 285 * Is this is the item we are looking for? We could have first 286 * checked if the hashes match but op->equal() may very well be 287 * just as fast as op->hash(). 288 */ 289 if (h->op->equal(cur_link, item)) { 290 return cur_link; 291 } 292 } 293 294 return NULL; 267 295 } 268 296 … … 278 306 * @return Returns the number of removed items. 279 307 */ 280 size_t hash_table_remove(hash_table_t *h, unsigned long key[], size_t key_cnt) 281 { 282 assert(h && h->bucket); 283 assert(h && h->op && h->op->hash && 284 h->op->remove_callback); 285 assert(key_cnt <= h->max_keys); 286 287 /* All keys are known, remove from a specific bucket. */ 288 if (key_cnt == h->max_keys) { 289 return remove_duplicates(h, key); 290 } else { 291 /* 292 * Fewer keys were passed. 293 * Any partially matching entries are to be removed. 294 */ 295 return remove_matching(h, key, key_cnt); 296 } 308 size_t hash_table_remove(hash_table_t *h, void *key) 309 { 310 assert(h && h->bucket); 311 assert(!h->apply_ongoing); 312 313 size_t idx = h->op->key_hash(key) % h->bucket_cnt; 314 315 size_t removed = 0; 316 317 list_foreach_safe(h->bucket[idx], cur, next) { 318 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 319 320 if (h->op->key_equal(key, cur_link)) { 321 ++removed; 322 list_remove(cur); 323 h->op->remove_callback(cur_link); 324 } 325 } 326 327 h->item_cnt -= removed; 328 shrink_if_needed(h); 329 330 return removed; 297 331 } 298 332 299 333 /** Removes an item already present in the table. The item must be in the table.*/ 300 void hash_table_remove_item(hash_table_t *h, link_t *item)334 void hash_table_remove_item(hash_table_t *h, ht_link_t *item) 301 335 { 302 336 assert(item); 303 337 assert(h && h->bucket); 304 305 remove_item(h, item); 306 } 307 308 /** Unlink the item from a bucket, update statistics and resize if needed. */ 309 static inline void remove_item(hash_table_t *h, link_t *item) 310 { 311 assert(item); 312 313 list_remove(item); 314 item_removed(h); 338 assert(link_in_use(&item->link)); 339 340 list_remove(&item->link); 341 --h->item_cnt; 315 342 h->op->remove_callback(item); 316 } 317 318 /** Removes all items matching key in the bucket key hashes to. */ 319 static size_t remove_duplicates(hash_table_t *h, unsigned long key[]) 320 { 321 assert(h && h->bucket); 322 assert(h->op && h->op->key_hash && h->op->match); 323 324 size_t key_hash = h->op->key_hash(key); 325 size_t idx = key_hash % h->bucket_cnt; 326 327 assert(idx < h->bucket_cnt); 328 329 size_t removed = 0; 330 331 list_foreach_safe(h->bucket[idx], cur, next) { 332 if (h->op->match(key, h->max_keys, cur)) { 333 ++removed; 334 remove_item(h, cur); 335 } 336 } 337 338 return removed; 339 } 340 341 /** Removes all items in any bucket in the table that match the partial key. */ 342 static size_t remove_matching(hash_table_t *h, unsigned long key[], 343 size_t key_cnt) 344 { 345 assert(h && h->bucket); 346 assert(key_cnt < h->max_keys); 347 348 size_t removed = 0; 349 /* 350 * Fewer keys were passed. 351 * Any partially matching entries are to be removed. 352 */ 343 shrink_if_needed(h); 344 } 345 346 /** Apply function to all items in hash table. 347 * 348 * @param h Hash table. 349 * @param f Function to be applied. Return false if no more items 350 * should be visited. The functor may only delete the supplied 351 * item. It must not delete the successor of the item passed 352 * in the first argument. 353 * @param arg Argument to be passed to the function. 354 */ 355 void hash_table_apply(hash_table_t *h, bool (*f)(ht_link_t *, void *), void *arg) 356 { 357 assert(f); 358 assert(h && h->bucket); 359 360 if (h->item_cnt == 0) 361 return; 362 363 h->apply_ongoing = true; 364 353 365 for (size_t idx = 0; idx < h->bucket_cnt; ++idx) { 354 366 list_foreach_safe(h->bucket[idx], cur, next) { 355 if (h->op->match(key, key_cnt, cur)) { 356 ++removed; 357 remove_item(h, cur); 358 } 359 } 360 } 361 362 return removed; 363 367 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 368 /* 369 * The next pointer had already been saved. f() may safely 370 * delete cur (but not next!). 371 */ 372 if (!f(cur_link, arg)) 373 return; 374 } 375 } 376 377 h->apply_ongoing = false; 378 379 shrink_if_needed(h); 380 grow_if_needed(h); 364 381 } 365 382 … … 392 409 } 393 410 394 /** Allocates and rehashes items to a new table. Frees the old table. */ 395 static void resize(hash_table_t *h, size_t new_bucket_cnt) 396 { 397 assert(h && h->bucket); 398 399 list_t *new_buckets; 400 401 /* Leave the table as is if we cannot resize. */ 402 if (!alloc_table(new_bucket_cnt, &new_buckets)) 403 return; 404 405 /* Rehash all the items to the new table. */ 406 for (size_t old_idx = 0; old_idx < h->bucket_cnt; ++old_idx) { 407 list_foreach_safe(h->bucket[old_idx], cur, next) { 408 size_t new_idx = h->op->hash(cur) % new_bucket_cnt; 409 list_remove(cur); 410 list_append(cur, &new_buckets[new_idx]); 411 } 412 } 413 414 free(h->bucket); 415 h->bucket = new_buckets; 416 h->bucket_cnt = new_bucket_cnt; 417 } 418 419 /** Shrinks the table if needed. */ 420 static void item_removed(hash_table_t *h) 421 { 422 --h->items; 423 424 if (HT_MIN_BUCKETS < h->items && h->items <= HT_MAX_LOAD * h->bucket_cnt / 4) { 411 412 /** Shrinks the table if the table is only sparely populated. */ 413 static inline void shrink_if_needed(hash_table_t *h) 414 { 415 if (h->item_cnt <= h->full_item_cnt / 4 && HT_MIN_BUCKETS < h->bucket_cnt) { 425 416 /* 426 417 * Keep the bucket_cnt odd (possibly also prime). … … 432 423 } 433 424 434 /** Grows the table if needed. */ 435 static void item_inserted(hash_table_t *h) 436 { 437 ++h->items; 438 425 /** Grows the table if table load exceeds the maximum allowed. */ 426 static inline void grow_if_needed(hash_table_t *h) 427 { 439 428 /* Grow the table if the average bucket load exceeds the maximum. */ 440 if ( HT_MAX_LOAD * h->bucket_cnt < h->items) {429 if (h->full_item_cnt < h->item_cnt) { 441 430 /* Keep the bucket_cnt odd (possibly also prime). */ 442 431 size_t new_bucket_cnt = 2 * h->bucket_cnt + 1; … … 445 434 } 446 435 436 /** Allocates and rehashes items to a new table. Frees the old table. */ 437 static void resize(hash_table_t *h, size_t new_bucket_cnt) 438 { 439 assert(h && h->bucket); 440 assert(HT_MIN_BUCKETS <= new_bucket_cnt); 441 442 /* We are traversing the table and resizing would mess up the buckets. */ 443 if (h->apply_ongoing) 444 return; 445 446 list_t *new_buckets; 447 448 /* Leave the table as is if we cannot resize. */ 449 if (!alloc_table(new_bucket_cnt, &new_buckets)) 450 return; 451 452 if (0 < h->item_cnt) { 453 /* Rehash all the items to the new table. */ 454 for (size_t old_idx = 0; old_idx < h->bucket_cnt; ++old_idx) { 455 list_foreach_safe(h->bucket[old_idx], cur, next) { 456 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 457 458 size_t new_idx = h->op->hash(cur_link) % new_bucket_cnt; 459 list_remove(cur); 460 list_append(cur, &new_buckets[new_idx]); 461 } 462 } 463 } 464 465 free(h->bucket); 466 h->bucket = new_buckets; 467 h->bucket_cnt = new_bucket_cnt; 468 h->full_item_cnt = h->max_load * h->bucket_cnt; 469 } 470 447 471 448 472 /** @} -
uspace/lib/c/generic/async.c
rb17518e rbc216a0 202 202 /* Client connection data */ 203 203 typedef struct { 204 link_t link;204 ht_link_t link; 205 205 206 206 task_id_t in_task_id; … … 214 214 215 215 /** Hash table link. */ 216 link_t link;216 ht_link_t link; 217 217 218 218 /** Incoming client task ID. */ … … 390 390 static LIST_INITIALIZE(timeout_list); 391 391 392 static size_t client_key_hash(unsigned long key[]) 393 { 394 assert(key); 395 /* LOWER32(in_task_id) */ 396 return key[0] >> 4; 397 } 398 399 static size_t client_hash(const link_t *item) 400 { 401 client_t *client = hash_table_get_instance(item, client_t, link); 402 403 unsigned long key[2] = { 404 LOWER32(client->in_task_id), 405 UPPER32(client->in_task_id), 406 }; 407 408 return client_key_hash(key); 409 } 410 411 static bool client_match(unsigned long key[], size_t keys, const link_t *item) 412 { 413 assert(key); 414 assert(keys == 2); 415 assert(item); 416 417 client_t *client = hash_table_get_instance(item, client_t, link); 418 return (key[0] == LOWER32(client->in_task_id) && 419 (key[1] == UPPER32(client->in_task_id))); 392 static size_t client_key_hash(void *k) 393 { 394 task_id_t key = *(task_id_t*)k; 395 return key; 396 } 397 398 static size_t client_hash(const ht_link_t *item) 399 { 400 client_t *client = hash_table_get_inst(item, client_t, link); 401 return client_key_hash(&client->in_task_id); 402 } 403 404 static bool client_key_equal(void *k, const ht_link_t *item) 405 { 406 task_id_t key = *(task_id_t*)k; 407 client_t *client = hash_table_get_inst(item, client_t, link); 408 return key == client->in_task_id; 420 409 } 421 410 … … 425 414 .hash = client_hash, 426 415 .key_hash = client_key_hash, 427 . match = client_match,416 .key_equal = client_key_equal, 428 417 .equal = 0, 429 418 .remove_callback = 0 … … 437 426 * 438 427 */ 439 static size_t conn_key_hash(unsigned long key[]) 440 { 441 assert(key); 442 return key[0] >> 4; 443 } 444 445 static size_t conn_hash(const link_t *item) 446 { 447 connection_t *conn = hash_table_get_instance(item, connection_t, link); 448 unsigned long key = conn->in_phone_hash; 449 return conn_key_hash(&key); 450 } 451 452 /** Compare hash table item with a key. 453 * 454 * @param key Array containing the source phone hash as the only item. 455 * @param keys Expected 1 but ignored. 456 * @param item Connection hash table item. 457 * 458 * @return True on match, false otherwise. 459 * 460 */ 461 static bool conn_match(unsigned long key[], size_t keys, const link_t *item) 462 { 463 assert(key); 464 assert(item); 465 466 connection_t *conn = hash_table_get_instance(item, connection_t, link); 467 return (key[0] == conn->in_phone_hash); 468 } 469 470 static bool conn_equal(const link_t *item1, const link_t *item2) 471 { 472 connection_t *c1 = hash_table_get_instance(item1, connection_t, link); 473 connection_t *c2 = hash_table_get_instance(item2, connection_t, link); 474 475 return c1->in_phone_hash == c2->in_phone_hash; 476 } 477 478 static void conn_remove(link_t *item) 479 { 480 } 428 static size_t conn_key_hash(void *key) 429 { 430 sysarg_t in_phone_hash = *(sysarg_t*)key; 431 return in_phone_hash ; 432 } 433 434 static size_t conn_hash(const ht_link_t *item) 435 { 436 connection_t *conn = hash_table_get_inst(item, connection_t, link); 437 return conn_key_hash(&conn->in_phone_hash); 438 } 439 440 static bool conn_key_equal(void *key, const ht_link_t *item) 441 { 442 sysarg_t in_phone_hash = *(sysarg_t*)key; 443 connection_t *conn = hash_table_get_inst(item, connection_t, link); 444 return (in_phone_hash == conn->in_phone_hash); 445 } 446 481 447 482 448 /** Operations for the connection hash table. */ … … 484 450 .hash = conn_hash, 485 451 .key_hash = conn_key_hash, 486 . match = conn_match,487 .equal = conn_equal,488 .remove_callback = conn_remove452 .key_equal = conn_key_equal, 453 .equal = 0, 454 .remove_callback = 0 489 455 }; 490 456 … … 534 500 futex_down(&async_futex); 535 501 536 unsigned long key = call->in_phone_hash; 537 link_t *hlp = hash_table_find(&conn_hash_table, &key); 502 ht_link_t *hlp = hash_table_find(&conn_hash_table, &call->in_phone_hash); 538 503 539 504 if (!hlp) { … … 542 507 } 543 508 544 connection_t *conn = hash_table_get_inst ance(hlp, connection_t, link);509 connection_t *conn = hash_table_get_inst(hlp, connection_t, link); 545 510 546 511 msg_t *msg = malloc(sizeof(*msg)); … … 722 687 static client_t *async_client_get(task_id_t client_id, bool create) 723 688 { 724 unsigned long key[2] = {725 LOWER32(client_id),726 UPPER32(client_id),727 };728 689 client_t *client = NULL; 729 690 730 691 futex_down(&async_futex); 731 link_t *lnk = hash_table_find(&client_hash_table, key);692 ht_link_t *lnk = hash_table_find(&client_hash_table, &client_id); 732 693 if (lnk) { 733 client = hash_table_get_inst ance(lnk, client_t, link);694 client = hash_table_get_inst(lnk, client_t, link); 734 695 atomic_inc(&client->refcnt); 735 696 } else if (create) { … … 751 712 { 752 713 bool destroy; 753 unsigned long key[2] = { 754 LOWER32(client->in_task_id), 755 UPPER32(client->in_task_id) 756 }; 757 714 758 715 futex_down(&async_futex); 759 716 760 717 if (atomic_predec(&client->refcnt) == 0) { 761 hash_table_remove(&client_hash_table, key, 2);718 hash_table_remove(&client_hash_table, &client->in_task_id); 762 719 destroy = true; 763 720 } else … … 855 812 */ 856 813 futex_down(&async_futex); 857 unsigned long key = fibril_connection->in_phone_hash; 858 hash_table_remove(&conn_hash_table, &key, 1); 814 hash_table_remove(&conn_hash_table, &fibril_connection->in_phone_hash); 859 815 futex_up(&async_futex); 860 816 … … 1134 1090 void __async_init(void) 1135 1091 { 1136 if (!hash_table_create(&client_hash_table, 0, 2, &client_hash_table_ops))1092 if (!hash_table_create(&client_hash_table, 0, 0, &client_hash_table_ops)) 1137 1093 abort(); 1138 1094 1139 if (!hash_table_create(&conn_hash_table, 0, 1, &conn_hash_table_ops))1095 if (!hash_table_create(&conn_hash_table, 0, 0, &conn_hash_table_ops)) 1140 1096 abort(); 1141 1097 -
uspace/lib/c/include/adt/hash_table.h
rb17518e rbc216a0 1 1 /* 2 2 * Copyright (c) 2006 Jakub Jermar 3 * Copyright (c) 2012 Adam Hraska 4 * 3 5 * All rights reserved. 4 6 * … … 39 41 #include <unistd.h> 40 42 #include <bool.h> 43 #include <macros.h> 41 44 45 /** Opaque hash table link type. */ 46 typedef struct ht_link { 47 link_t link; 48 } ht_link_t; 42 49 43 50 /** Set of operations for hash table. */ 44 51 typedef struct { 45 /** Returns the hash of the key stored in the item. 46 */ 47 size_t (*hash)(const link_t *item); 52 /** Returns the hash of the key stored in the item (ie its lookup key). */ 53 size_t (*hash)(const ht_link_t *item); 48 54 49 /** Returns the hash of the key. 50 */ 51 size_t (*key_hash)(unsigned long key[]); 55 /** Returns the hash of the key. */ 56 size_t (*key_hash)(void *key); 52 57 53 /** Hash table item match function. 54 * 55 * @param key Array of keys that will be compared with item. It is 56 * not necessary to pass all keys. 57 * 58 * @return True if the keys match, false otherwise. 59 * 60 */ 61 bool (*match)(unsigned long key[], size_t keys, const link_t *item); 58 /** True if the items are equal (have the same lookup keys). */ 59 bool (*equal)(const ht_link_t *item1, const ht_link_t *item2); 62 60 63 /** 64 */ 65 bool (*equal)(const link_t *item1, const link_t *item2); 66 61 /** Returns true if the key is equal to the item's lookup key. */ 62 bool (*key_equal)(void *key, const ht_link_t *item); 63 67 64 /** Hash table item removal callback. 68 65 * … … 71 68 * @param item Item that was removed from the hash table. 72 69 */ 73 void (*remove_callback)( link_t *item);70 void (*remove_callback)(ht_link_t *item); 74 71 } hash_table_ops_t; 75 72 76 73 /** Hash table structure. */ 77 74 typedef struct { 75 hash_table_ops_t *op; 78 76 list_t *bucket; 79 77 size_t bucket_cnt; 80 size_t max_keys; 81 size_t items; 82 hash_table_ops_t *op; 78 size_t full_item_cnt; 79 size_t item_cnt; 80 size_t max_load; 81 bool apply_ongoing; 83 82 } hash_table_t; 84 83 85 #define hash_table_get_inst ance(item, type, member) \86 list_get_instance((item), type, member)84 #define hash_table_get_inst(item, type, member) \ 85 member_to_inst((item), type, member) 87 86 88 87 extern bool hash_table_create(hash_table_t *, size_t, size_t, 89 88 hash_table_ops_t *); 89 extern void hash_table_destroy(hash_table_t *); 90 91 extern bool hash_table_empty(hash_table_t *); 92 extern size_t hash_table_size(hash_table_t *); 93 90 94 extern void hash_table_clear(hash_table_t *); 91 extern void hash_table_insert(hash_table_t *, link_t *);92 extern bool hash_table_insert_unique(hash_table_t *, link_t *);93 extern link_t *hash_table_find(const hash_table_t *, unsigned long []);94 extern size_t hash_table_remove(hash_table_t *, unsigned long [], size_t);95 extern void hash_table_remove_item(hash_table_t *, link_t*);96 extern void hash_table_ destroy(hash_table_t *);97 extern void hash_table_apply(hash_table_t *, bool (*)( link_t *, void *),95 extern void hash_table_insert(hash_table_t *, ht_link_t *); 96 extern bool hash_table_insert_unique(hash_table_t *, ht_link_t *); 97 extern ht_link_t *hash_table_find(const hash_table_t *, void *); 98 extern ht_link_t *hash_table_find_next(const hash_table_t *, ht_link_t *); 99 extern size_t hash_table_remove(hash_table_t *, void *); 100 extern void hash_table_remove_item(hash_table_t *, ht_link_t *); 101 extern void hash_table_apply(hash_table_t *, bool (*)(ht_link_t *, void *), 98 102 void *); 99 103 -
uspace/lib/c/include/adt/list.h
rb17518e rbc216a0 105 105 assert(((link)->prev == NULL) && ((link)->next == NULL)) 106 106 107 /** Returns true if the link is definitely part of a list. False if not sure. */ 108 static inline int link_in_use(link_t *link) 109 { 110 return link->prev != NULL && link->next != NULL; 111 } 112 107 113 /** Initialize doubly-linked circular list link 108 114 * -
uspace/lib/nic/include/nic.h
rb17518e rbc216a0 40 40 41 41 #include <adt/list.h> 42 #include <adt/hash_table.h> 42 43 #include <ddf/driver.h> 43 44 #include <device/hw_res_parsed.h> … … 53 54 */ 54 55 typedef struct nic_wol_virtue { 55 link_t item;56 ht_link_t item; 56 57 nic_wv_id_t id; 57 58 nic_wv_type_t type; -
uspace/lib/nic/src/nic_addr_db.c
rb17518e rbc216a0 36 36 */ 37 37 #include "nic_addr_db.h" 38 #include "libarch/common.h" 38 39 #include <assert.h> 39 40 #include <stdlib.h> … … 43 44 #include <adt/hash_table.h> 44 45 #include <macros.h> 45 46 /* The key count hash table field is not used. Use this dummy value. */ 47 #define KEY_CNT 1 48 49 /** 50 * Maximal length of addresses in the DB (in bytes). 51 */ 52 #define NIC_ADDR_MAX_LENGTH 16 46 #include <stdint.h> 47 53 48 54 49 /** … … 56 51 */ 57 52 typedef struct nic_addr_entry { 58 link_t link; 59 uint8_t addr[NIC_ADDR_MAX_LENGTH]; 53 ht_link_t link; 54 uint8_t len; 55 uint8_t addr[1]; 60 56 } nic_addr_entry_t; 61 57 … … 64 60 * Hash table helper functions 65 61 */ 66 67 static bool nic_addr_match(unsigned long *key, size_t key_cnt, 68 const link_t *item) 69 { 70 uint8_t *addr = (uint8_t*)key; 71 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 72 73 return 0 == bcmp(entry->addr, addr, NIC_ADDR_MAX_LENGTH); 74 } 75 76 static size_t nic_addr_key_hash(unsigned long *key) 77 { 78 uint8_t *addr = (uint8_t*)key; 62 typedef struct { 63 size_t len; 64 const uint8_t *addr; 65 } addr_key_t; 66 67 static bool nic_addr_key_equal(void *key_arg, const ht_link_t *item) 68 { 69 addr_key_t *key = (addr_key_t*)key_arg; 70 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 71 72 return 0 == bcmp(entry->addr, key->addr, entry->len); 73 } 74 75 static size_t addr_hash(size_t len, const uint8_t *addr) 76 { 79 77 size_t hash = 0; 80 81 for ( int i = NIC_ADDR_MAX_LENGTH - 1; i >= 0; --i) {82 hash = (hash << 8) ^ (hash >> 24) ^ addr[i];78 79 for (size_t i = 0; i < len; ++i) { 80 hash = (hash << 5) ^ addr[i]; 83 81 } 84 82 … … 86 84 } 87 85 88 static size_t nic_addr_hash(const link_t *item) 89 { 90 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 91 92 unsigned long *key = (unsigned long*)entry->addr; 93 return nic_addr_key_hash(key); 94 } 95 96 static void nic_addr_removed(link_t *item) 86 static size_t nic_addr_key_hash(void *k) 87 { 88 addr_key_t *key = (addr_key_t*)k; 89 return addr_hash(key->len, key->addr); 90 } 91 92 static size_t nic_addr_hash(const ht_link_t *item) 93 { 94 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 95 return addr_hash(entry->len, entry->addr); 96 } 97 98 static void nic_addr_removed(ht_link_t *item) 97 99 { 98 100 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); … … 104 106 .hash = nic_addr_hash, 105 107 .key_hash = nic_addr_key_hash, 106 . match = nic_addr_match,108 .key_equal = nic_addr_key_equal, 107 109 .equal = 0, 108 110 .remove_callback = nic_addr_removed … … 122 124 { 123 125 assert(db); 124 if (addr_len > NIC_ADDR_MAX_LENGTH) { 126 127 if (addr_len > UCHAR_MAX) 125 128 return EINVAL; 126 } 127 128 if (!hash_table_create(&db->set, 0, KEY_CNT, &set_ops)) 129 130 if (!hash_table_create(&db->set, 0, 0, &set_ops)) 129 131 return ENOMEM; 130 132 … … 152 154 { 153 155 assert(db); 154 nic_addr_db_clear(db);155 156 hash_table_destroy(&db->set); 156 157 } … … 171 172 { 172 173 assert(db && addr); 173 /* Ugly type-punning hack. */ 174 unsigned long *key = (unsigned long*)addr; 175 176 if (hash_table_find(&db->set, key)) 174 175 addr_key_t key = { 176 .len = db->addr_len, 177 .addr = addr 178 }; 179 180 if (hash_table_find(&db->set, &key)) 177 181 return EEXIST; 178 182 179 nic_addr_entry_t *entry = malloc(sizeof(nic_addr_entry_t) );183 nic_addr_entry_t *entry = malloc(sizeof(nic_addr_entry_t) + db->addr_len - 1); 180 184 if (entry == NULL) 181 185 return ENOMEM; 182 183 link_initialize(&entry->link); 184 185 bzero(entry->addr, NIC_ADDR_MAX_LENGTH); 186 187 entry->len = (uint8_t) db->addr_len; 186 188 memcpy(entry->addr, addr, db->addr_len); 187 189 … … 202 204 { 203 205 assert(db && addr); 204 unsigned long *key = (unsigned long*)addr; 205 206 link_t *item = hash_table_find(&db->set, key); 207 208 if (item) { 209 hash_table_remove_item(&db->set, item); 206 207 addr_key_t key = { 208 .len = db->addr_len, 209 .addr = addr 210 }; 211 212 if (hash_table_remove(&db->set, &key)) 210 213 return EOK; 211 } else {214 else 212 215 return ENOENT; 213 }214 216 } 215 217 … … 225 227 { 226 228 assert(db && addr); 227 unsigned long *key = (unsigned long*)addr; 228 229 return 0 != hash_table_find(&db->set, key); 229 230 addr_key_t key = { 231 .len = db->addr_len, 232 .addr = addr 233 }; 234 235 return 0 != hash_table_find(&db->set, &key); 230 236 } 231 237 … … 241 247 * Helper function for nic_addr_db_foreach 242 248 */ 243 static bool nic_addr_db_fe_helper( link_t *item, void *arg)249 static bool nic_addr_db_fe_helper(ht_link_t *item, void *arg) 244 250 { 245 251 nic_addr_db_fe_arg_t *hs = (nic_addr_db_fe_arg_t *) arg; -
uspace/lib/nic/src/nic_wol_virtues.c
rb17518e rbc216a0 37 37 38 38 #include "nic_wol_virtues.h" 39 #include "nic.h" 39 40 #include <assert.h> 40 41 #include <errno.h> … … 45 46 */ 46 47 47 static size_t nic_wv_key_hash( unsigned long keys[])48 { 49 return keys[0];50 } 51 52 static size_t nic_wv_hash(const link_t *item)48 static size_t nic_wv_key_hash(void *key) 49 { 50 return *(nic_wv_id_t*) key; 51 } 52 53 static size_t nic_wv_hash(const ht_link_t *item) 53 54 { 54 55 nic_wol_virtue_t *virtue = (nic_wol_virtue_t *) item; 55 unsigned long key = virtue->id; 56 return nic_wv_key_hash(&key); 57 } 58 59 static bool nic_wv_match(unsigned long key[], size_t keys, const link_t *item) 56 return virtue->id; 57 } 58 59 static bool nic_wv_key_equal(void *key, const ht_link_t *item) 60 60 { 61 61 nic_wol_virtue_t *virtue = (nic_wol_virtue_t *) item; 62 return (virtue->id == (nic_wv_id_t) key[0]);62 return (virtue->id == *(nic_wv_id_t*) key); 63 63 } 64 64 … … 76 76 wvs->table_operations.hash = nic_wv_hash; 77 77 wvs->table_operations.key_hash = nic_wv_key_hash; 78 wvs->table_operations. match = nic_wv_match;78 wvs->table_operations.key_equal = nic_wv_key_equal; 79 79 wvs->table_operations.equal = 0; 80 80 wvs->table_operations.remove_callback = 0; 81 81 82 if (!hash_table_create(&wvs->table, 0, 1, &wvs->table_operations)) {82 if (!hash_table_create(&wvs->table, 0, 0, &wvs->table_operations)) { 83 83 return ENOMEM; 84 84 } … … 168 168 do { 169 169 virtue->id = wvs->next_id++; 170 } while (NULL != 171 hash_table_find(&wvs->table, (unsigned long *) &virtue->id)); 170 } while (NULL != hash_table_find(&wvs->table, &virtue->id)); 172 171 hash_table_insert(&wvs->table, &virtue->item); 173 172 virtue->next = wvs->lists[virtue->type]; … … 188 187 nic_wol_virtue_t *nic_wol_virtues_remove(nic_wol_virtues_t *wvs, nic_wv_id_t id) 189 188 { 190 nic_wol_virtue_t *virtue = (nic_wol_virtue_t *)191 hash_table_find(&wvs->table, (unsigned long *)&id);189 nic_wol_virtue_t *virtue = 190 (nic_wol_virtue_t *) hash_table_find(&wvs->table, &id); 192 191 if (virtue == NULL) { 193 192 return NULL; … … 195 194 196 195 /* Remove from filter_table */ 197 hash_table_remove (&wvs->table, (unsigned long *) &id, 1);196 hash_table_remove_item(&wvs->table, &virtue->item); 198 197 199 198 /* Remove from filter_types */ … … 232 231 * constant virtue the retyping is correct. 233 232 */ 234 link_t *virtue = hash_table_find( 235 &((nic_wol_virtues_t *) wvs)->table, (unsigned long *) &id); 233 ht_link_t *virtue = hash_table_find(&((nic_wol_virtues_t *) wvs)->table, &id); 236 234 return (const nic_wol_virtue_t *) virtue; 237 235 } -
uspace/srv/devman/devman.c
rb17518e rbc216a0 66 66 /* hash table operations */ 67 67 68 static size_t devices_key_hash(unsigned long key[]) 69 { 70 return key[0]; 71 } 72 73 static size_t devman_devices_hash(const link_t *item) 74 { 75 dev_node_t *dev = hash_table_get_instance(item, dev_node_t, devman_dev); 76 unsigned long key = dev->handle; 77 return devices_key_hash(&key); 78 } 79 80 static size_t devman_functions_hash(const link_t *item) 81 { 82 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devman_fun); 83 unsigned long key = fun->handle; 84 return devices_key_hash(&key); 85 } 86 87 static size_t loc_functions_hash(const link_t *item) 88 { 89 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, loc_fun); 90 unsigned long key = fun->service_id; 91 return devices_key_hash(&key); 92 } 93 94 static bool devman_devices_match(unsigned long key[], size_t keys, 95 const link_t *item) 96 { 97 dev_node_t *dev = hash_table_get_instance(item, dev_node_t, devman_dev); 98 return (dev->handle == (devman_handle_t) key[0]); 99 } 100 101 static bool devman_functions_match(unsigned long key[], size_t keys, 102 const link_t *item) 103 { 104 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, devman_fun); 105 return (fun->handle == (devman_handle_t) key[0]); 106 } 107 108 static bool loc_functions_match(unsigned long key[], size_t keys, 109 const link_t *item) 110 { 111 fun_node_t *fun = hash_table_get_instance(item, fun_node_t, loc_fun); 112 return (fun->service_id == (service_id_t) key[0]); 68 static inline size_t handle_key_hash(void *key) 69 { 70 devman_handle_t handle = *(devman_handle_t*)key; 71 return handle; 72 } 73 74 static size_t devman_devices_hash(const ht_link_t *item) 75 { 76 dev_node_t *dev = hash_table_get_inst(item, dev_node_t, devman_dev); 77 return handle_key_hash(&dev->handle); 78 } 79 80 static size_t devman_functions_hash(const ht_link_t *item) 81 { 82 fun_node_t *fun = hash_table_get_inst(item, fun_node_t, devman_fun); 83 return handle_key_hash(&fun->handle); 84 } 85 86 static bool devman_devices_key_equal(void *key, const ht_link_t *item) 87 { 88 devman_handle_t handle = *(devman_handle_t*)key; 89 dev_node_t *dev = hash_table_get_inst(item, dev_node_t, devman_dev); 90 return dev->handle == handle; 91 } 92 93 static bool devman_functions_key_equal(void *key, const ht_link_t *item) 94 { 95 devman_handle_t handle = *(devman_handle_t*)key; 96 fun_node_t *fun = hash_table_get_inst(item, fun_node_t, devman_fun); 97 return fun->handle == handle; 98 } 99 100 static inline size_t service_id_key_hash(void *key) 101 { 102 service_id_t service_id = *(service_id_t*)key; 103 return service_id; 104 } 105 106 static size_t loc_functions_hash(const ht_link_t *item) 107 { 108 fun_node_t *fun = hash_table_get_inst(item, fun_node_t, loc_fun); 109 return service_id_key_hash(&fun->service_id); 110 } 111 112 static bool loc_functions_key_equal(void *key, const ht_link_t *item) 113 { 114 service_id_t service_id = *(service_id_t*)key; 115 fun_node_t *fun = hash_table_get_inst(item, fun_node_t, loc_fun); 116 return fun->service_id == service_id; 113 117 } 114 118 … … 116 120 static hash_table_ops_t devman_devices_ops = { 117 121 .hash = devman_devices_hash, 118 .key_hash = devices_key_hash,119 . match = devman_devices_match,122 .key_hash = handle_key_hash, 123 .key_equal = devman_devices_key_equal, 120 124 .equal = 0, 121 125 .remove_callback = 0 … … 124 128 static hash_table_ops_t devman_functions_ops = { 125 129 .hash = devman_functions_hash, 126 .key_hash = devices_key_hash,127 . match = devman_functions_match,130 .key_hash = handle_key_hash, 131 .key_equal = devman_functions_key_equal, 128 132 .equal = 0, 129 133 .remove_callback = 0 … … 132 136 static hash_table_ops_t loc_devices_ops = { 133 137 .hash = loc_functions_hash, 134 .key_hash = devices_key_hash,135 . match = loc_functions_match,138 .key_hash = service_id_key_hash, 139 .key_equal = loc_functions_key_equal, 136 140 .equal = 0, 137 141 .remove_callback = 0 … … 998 1002 tree->current_handle = 0; 999 1003 1000 hash_table_create(&tree->devman_devices, 0, 1, &devman_devices_ops);1001 hash_table_create(&tree->devman_functions, 0, 1, &devman_functions_ops);1002 hash_table_create(&tree->loc_functions, 0, 1, &loc_devices_ops);1004 hash_table_create(&tree->devman_devices, 0, 0, &devman_devices_ops); 1005 hash_table_create(&tree->devman_functions, 0, 0, &devman_functions_ops); 1006 hash_table_create(&tree->loc_functions, 0, 0, &loc_devices_ops); 1003 1007 1004 1008 fibril_rwlock_initialize(&tree->rwlock); … … 1034 1038 list_initialize(&dev->functions); 1035 1039 link_initialize(&dev->driver_devices); 1036 link_initialize(&dev->devman_dev);1037 1040 1038 1041 return dev; … … 1082 1085 dev_node_t *find_dev_node_no_lock(dev_tree_t *tree, devman_handle_t handle) 1083 1086 { 1084 unsigned long key = handle;1085 link_t *link;1086 1087 1087 assert(fibril_rwlock_is_locked(&tree->rwlock)); 1088 1088 1089 link = hash_table_find(&tree->devman_devices, &key);1089 ht_link_t *link = hash_table_find(&tree->devman_devices, &handle); 1090 1090 if (link == NULL) 1091 1091 return NULL; 1092 1092 1093 return hash_table_get_inst ance(link, dev_node_t, devman_dev);1093 return hash_table_get_inst(link, dev_node_t, devman_dev); 1094 1094 } 1095 1095 … … 1165 1165 link_initialize(&fun->dev_functions); 1166 1166 list_initialize(&fun->match_ids.ids); 1167 link_initialize(&fun->devman_fun);1168 link_initialize(&fun->loc_fun);1169 1167 1170 1168 return fun; … … 1215 1213 fun_node_t *find_fun_node_no_lock(dev_tree_t *tree, devman_handle_t handle) 1216 1214 { 1217 unsigned long key = handle;1218 link_t *link;1219 1215 fun_node_t *fun; 1220 1216 1221 1217 assert(fibril_rwlock_is_locked(&tree->rwlock)); 1222 1218 1223 link = hash_table_find(&tree->devman_functions, &key);1219 ht_link_t *link = hash_table_find(&tree->devman_functions, &handle); 1224 1220 if (link == NULL) 1225 1221 return NULL; 1226 1222 1227 fun = hash_table_get_inst ance(link, fun_node_t, devman_fun);1223 fun = hash_table_get_inst(link, fun_node_t, devman_fun); 1228 1224 1229 1225 return fun; … … 1324 1320 1325 1321 /* Remove node from the handle-to-node map. */ 1326 unsigned long key = dev->handle; 1327 hash_table_remove(&tree->devman_devices, &key, 1); 1322 hash_table_remove(&tree->devman_devices, &dev->handle); 1328 1323 1329 1324 /* Unlink from parent function. */ … … 1386 1381 1387 1382 /* Remove the node from the handle-to-node map. */ 1388 unsigned long key = fun->handle; 1389 hash_table_remove(&tree->devman_functions, &key, 1); 1383 hash_table_remove(&tree->devman_functions, &fun->handle); 1390 1384 1391 1385 /* Remove the node from the list of its parent's children. */ … … 1500 1494 { 1501 1495 fun_node_t *fun = NULL; 1502 link_t *link;1503 unsigned long key = (unsigned long) service_id;1504 1496 1505 1497 fibril_rwlock_read_lock(&tree->rwlock); 1506 link = hash_table_find(&tree->loc_functions, &key);1498 ht_link_t *link = hash_table_find(&tree->loc_functions, &service_id); 1507 1499 if (link != NULL) { 1508 fun = hash_table_get_inst ance(link, fun_node_t, loc_fun);1500 fun = hash_table_get_inst(link, fun_node_t, loc_fun); 1509 1501 fun_add_ref(fun); 1510 1502 } -
uspace/srv/devman/devman.h
rb17518e rbc216a0 150 150 * Used by the hash table of devices indexed by devman device handles. 151 151 */ 152 link_t devman_dev;152 ht_link_t devman_dev; 153 153 154 154 /** … … 201 201 * Used by the hash table of functions indexed by devman device handles. 202 202 */ 203 link_t devman_fun;203 ht_link_t devman_fun; 204 204 205 205 /** 206 206 * Used by the hash table of functions indexed by service IDs. 207 207 */ 208 link_t loc_fun;208 ht_link_t loc_fun; 209 209 }; 210 210 -
uspace/srv/fs/cdfs/cdfs_ops.c
rb17518e rbc216a0 37 37 */ 38 38 39 #include "cdfs_ops.h" 39 40 #include <bool.h> 40 41 #include <adt/hash_table.h> 42 #include <adt/hash.h> 41 43 #include <malloc.h> 42 44 #include <mem.h> … … 50 52 #include "cdfs.h" 51 53 #include "cdfs_endian.h" 52 #include "cdfs_ops.h"53 54 54 55 /** Standard CD-ROM block size */ 55 56 #define BLOCK_SIZE 2048 56 57 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 67 59 68 60 /** All root nodes have index 0 */ … … 203 195 service_id_t service_id; /**< Service ID of block device */ 204 196 205 link_t nh_link;/**< Nodes hash table link */197 ht_link_t nh_link; /**< Nodes hash table link */ 206 198 cdfs_dentry_type_t type; /**< Dentry type */ 207 199 … … 224 216 static hash_table_t nodes; 225 217 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 222 typedef struct { 223 service_id_t service_id; 224 fs_index_t index; 225 } ht_key_t; 226 227 static 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 233 static 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 239 static 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 247 static void nodes_remove_callback(ht_link_t *item) 248 { 249 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 267 250 268 251 assert(node->type == CDFS_DIRECTORY); … … 283 266 .hash = nodes_hash, 284 267 .key_hash = nodes_key_hash, 285 . match = nodes_match,286 .equal = nodes_equal,268 .key_equal = nodes_key_equal, 269 .equal = 0, 287 270 .remove_callback = nodes_remove_callback 288 271 }; … … 291 274 fs_index_t index) 292 275 { 293 unsigned long key[]= {294 [NODES_KEY_SRVC] = service_id,295 [NODES_KEY_INDEX] = index276 ht_key_t key = { 277 .index = index, 278 .service_id = service_id 296 279 }; 297 280 298 link_t *link = hash_table_find(&nodes,key);281 ht_link_t *link = hash_table_find(&nodes, &key); 299 282 if (link) { 300 283 cdfs_node_t *node = 301 hash_table_get_inst ance(link, cdfs_node_t, nh_link);284 hash_table_get_inst(link, cdfs_node_t, nh_link); 302 285 303 286 *rfn = FS_NODE(node); … … 325 308 node->opened = 0; 326 309 327 link_initialize(&node->nh_link);328 310 list_initialize(&node->cs_list); 329 311 } … … 517 499 static fs_node_t *get_cached_node(service_id_t service_id, fs_index_t index) 518 500 { 519 unsigned long key[]= {520 [NODES_KEY_SRVC] = service_id,521 [NODES_KEY_INDEX] = index501 ht_key_t key = { 502 .index = index, 503 .service_id = service_id 522 504 }; 523 505 524 link_t *link = hash_table_find(&nodes,key);506 ht_link_t *link = hash_table_find(&nodes, &key); 525 507 if (link) { 526 508 cdfs_node_t *node = 527 hash_table_get_inst ance(link, cdfs_node_t, nh_link);509 hash_table_get_inst(link, cdfs_node_t, nh_link); 528 510 return FS_NODE(node); 529 511 } … … 811 793 } 812 794 795 static 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 813 807 static void cdfs_instance_done(service_id_t service_id) 814 808 { 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); 820 810 block_cache_fini(service_id); 821 811 block_fini(service_id); … … 831 821 size_t *rbytes) 832 822 { 833 unsigned long key[]= {834 [NODES_KEY_SRVC] = service_id,835 [NODES_KEY_INDEX] = index823 ht_key_t key = { 824 .index = index, 825 .service_id = service_id 836 826 }; 837 827 838 link_t *link = hash_table_find(&nodes,key);828 ht_link_t *link = hash_table_find(&nodes, &key); 839 829 if (link == NULL) 840 830 return ENOENT; 841 831 842 832 cdfs_node_t *node = 843 hash_table_get_inst ance(link, cdfs_node_t, nh_link);833 hash_table_get_inst(link, cdfs_node_t, nh_link); 844 834 845 835 if (!node->processed) { … … 921 911 } 922 912 923 static bool cache_remove_closed( link_t *item, void *arg)913 static bool cache_remove_closed(ht_link_t *item, void *arg) 924 914 { 925 915 size_t *premove_cnt = (size_t*)arg; … … 927 917 /* Some nodes were requested to be removed from the cache. */ 928 918 if (0 < *premove_cnt) { 929 cdfs_node_t *node = hash_table_get_inst ance(item, cdfs_node_t, nh_link);919 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); 930 920 931 921 if (!node->opened) { … … 957 947 return EOK; 958 948 959 unsigned long key[]= {960 [NODES_KEY_SRVC] = service_id,961 [NODES_KEY_INDEX] = index949 ht_key_t key = { 950 .index = index, 951 .service_id = service_id 962 952 }; 963 953 964 link_t *link = hash_table_find(&nodes,key);954 ht_link_t *link = hash_table_find(&nodes, &key); 965 955 if (link == 0) 966 956 return ENOENT; 967 957 968 958 cdfs_node_t *node = 969 hash_table_get_inst ance(link, cdfs_node_t, nh_link);959 hash_table_get_inst(link, cdfs_node_t, nh_link); 970 960 971 961 assert(node->opened > 0); … … 1013 1003 bool cdfs_init(void) 1014 1004 { 1015 if (!hash_table_create(&nodes, 0, 2, &nodes_ops))1005 if (!hash_table_create(&nodes, 0, 0, &nodes_ops)) 1016 1006 return false; 1017 1007 -
uspace/srv/fs/exfat/exfat.h
rb17518e rbc216a0 106 106 typedef struct { 107 107 /** Used indices (position) hash table link. */ 108 link_t uph_link;108 ht_link_t uph_link; 109 109 /** Used indices (index) hash table link. */ 110 link_t uih_link;110 ht_link_t uih_link; 111 111 112 112 fibril_mutex_t lock; -
uspace/srv/fs/exfat/exfat_idx.c
rb17518e rbc216a0 41 41 #include <str.h> 42 42 #include <adt/hash_table.h> 43 #include <adt/hash.h> 43 44 #include <adt/list.h> 44 45 #include <assert.h> … … 91 92 if (lock) 92 93 fibril_mutex_lock(&unused_lock); 94 93 95 list_foreach(unused_list, l) { 94 96 u = list_get_instance(l, unused_t, link); … … 112 114 static hash_table_t up_hash; 113 115 114 #define UPH_SID_KEY 0 115 #define UPH_PFC_KEY 1 116 #define UPH_PDI_KEY 2 117 118 static size_t pos_key_hash(unsigned long key[]) 119 { 120 /* Inspired by Effective Java, 2nd edition. */ 121 size_t hash = 17; 122 123 hash = 31 * hash + key[UPH_PFC_KEY]; 124 hash = 31 * hash + key[UPH_PDI_KEY]; 125 hash = 31 * hash + key[UPH_SID_KEY]; 126 127 return hash; 128 } 129 130 static size_t pos_hash(const link_t *item) 131 { 132 exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uph_link); 133 134 unsigned long pkey[] = { 135 [UPH_SID_KEY] = fidx->service_id, 136 [UPH_PFC_KEY] = fidx->pfc, 137 [UPH_PDI_KEY] = fidx->pdi, 138 }; 139 140 return pos_key_hash(pkey); 141 } 142 143 static bool pos_match(unsigned long key[], size_t keys, const link_t *item) 144 { 145 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 116 typedef struct { 117 service_id_t service_id; 146 118 exfat_cluster_t pfc; 147 119 unsigned pdi; 148 exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uph_link); 149 150 switch (keys) { 151 case 1: 152 return (service_id == fidx->service_id); 153 case 3: 154 pfc = (exfat_cluster_t) key[UPH_PFC_KEY]; 155 pdi = (unsigned) key[UPH_PDI_KEY]; 156 return (service_id == fidx->service_id) && (pfc == fidx->pfc) && 157 (pdi == fidx->pdi); 158 default: 159 assert((keys == 1) || (keys == 3)); 160 } 161 162 return 0; 120 } pos_key_t; 121 122 static inline size_t pos_key_hash(void *key) 123 { 124 pos_key_t *pos = (pos_key_t*)key; 125 126 size_t hash = 0; 127 hash = hash_combine(pos->pfc, pos->pdi); 128 return hash_combine(hash, pos->service_id); 129 } 130 131 static size_t pos_hash(const ht_link_t *item) 132 { 133 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link); 134 135 pos_key_t pkey = { 136 .service_id = fidx->service_id, 137 .pfc = fidx->pfc, 138 .pdi = fidx->pdi, 139 }; 140 141 return pos_key_hash(&pkey); 142 } 143 144 static bool pos_key_equal(void *key, const ht_link_t *item) 145 { 146 pos_key_t *pos = (pos_key_t*)key; 147 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link); 148 149 return pos->service_id == fidx->service_id 150 && pos->pdi == fidx->pdi 151 && pos->pfc == fidx->pfc; 163 152 } 164 153 … … 166 155 .hash = pos_hash, 167 156 .key_hash = pos_key_hash, 168 . match = pos_match,157 .key_equal = pos_key_equal, 169 158 .equal = 0, 170 159 .remove_callback = 0, … … 177 166 static hash_table_t ui_hash; 178 167 179 #define UIH_SID_KEY 0 180 #define UIH_INDEX_KEY 1 181 182 static size_t idx_key_hash(unsigned long key[]) 183 { 184 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 185 fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY]; 186 187 /* 188 * Compute a simple hash unlimited by specific table size as per: 189 * Effective Java, 2nd edition. 190 */ 191 size_t hash = 17; 192 hash = 31 * hash + (size_t)service_id; 193 hash = 31 * hash + (size_t)index; 194 return hash; 195 } 196 197 static size_t idx_hash(const link_t *item) 198 { 199 exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uih_link); 200 201 unsigned long ikey[] = { 202 [UIH_SID_KEY] = fidx->service_id, 203 [UIH_INDEX_KEY] = fidx->index, 204 }; 205 206 return idx_key_hash(ikey); 207 } 208 209 static bool idx_match(unsigned long key[], size_t keys, const link_t *item) 210 { 211 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 168 typedef struct { 169 service_id_t service_id; 212 170 fs_index_t index; 213 exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uih_link); 214 215 switch (keys) { 216 case 1: 217 return (service_id == fidx->service_id); 218 case 2: 219 index = (fs_index_t) key[UIH_INDEX_KEY]; 220 return (service_id == fidx->service_id) && 221 (index == fidx->index); 222 default: 223 assert((keys == 1) || (keys == 2)); 224 } 225 226 return 0; 227 } 228 229 static void idx_remove_callback(link_t *item) 230 { 231 exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uih_link); 171 } idx_key_t; 172 173 static size_t idx_key_hash(void *key_arg) 174 { 175 idx_key_t *key = (idx_key_t*)key_arg; 176 return hash_combine(key->service_id, key->index); 177 } 178 179 static size_t idx_hash(const ht_link_t *item) 180 { 181 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); 182 return hash_combine(fidx->service_id, fidx->index); 183 } 184 185 static bool idx_key_equal(void *key_arg, const ht_link_t *item) 186 { 187 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); 188 idx_key_t *key = (idx_key_t*)key_arg; 189 190 return key->index == fidx->index && key->service_id == fidx->service_id; 191 } 192 193 static void idx_remove_callback(ht_link_t *item) 194 { 195 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); 232 196 233 197 free(fidx); … … 237 201 .hash = idx_hash, 238 202 .key_hash = idx_key_hash, 239 . match = idx_match,203 .key_equal = idx_key_equal, 240 204 .equal = 0, 241 205 .remove_callback = idx_remove_callback, … … 379 343 } 380 344 381 link_initialize(&fidx->uph_link);382 link_initialize(&fidx->uih_link);383 345 fibril_mutex_initialize(&fidx->lock); 384 346 fidx->service_id = service_id; … … 415 377 { 416 378 exfat_idx_t *fidx; 417 link_t *l;418 unsigned long pkey[]= {419 [UPH_SID_KEY]= service_id,420 [UPH_PFC_KEY]= pfc,421 [UPH_PDI_KEY]= pdi,379 380 pos_key_t pos_key = { 381 .service_id = service_id, 382 .pfc = pfc, 383 .pdi = pdi, 422 384 }; 423 385 424 386 fibril_mutex_lock(&used_lock); 425 l = hash_table_find(&up_hash, pkey);387 ht_link_t *l = hash_table_find(&up_hash, &pos_key); 426 388 if (l) { 427 fidx = hash_table_get_inst ance(l, exfat_idx_t, uph_link);389 fidx = hash_table_get_inst(l, exfat_idx_t, uph_link); 428 390 } else { 429 391 int rc; … … 456 418 void exfat_idx_hashout(exfat_idx_t *idx) 457 419 { 458 unsigned long pkey[] = { 459 [UPH_SID_KEY] = idx->service_id, 460 [UPH_PFC_KEY] = idx->pfc, 461 [UPH_PDI_KEY] = idx->pdi, 462 }; 463 464 fibril_mutex_lock(&used_lock); 465 hash_table_remove(&up_hash, pkey, 3); 420 fibril_mutex_lock(&used_lock); 421 hash_table_remove_item(&up_hash, &idx->uph_link); 466 422 fibril_mutex_unlock(&used_lock); 467 423 } … … 471 427 { 472 428 exfat_idx_t *fidx = NULL; 473 link_t *l; 474 unsigned long ikey[]= {475 [UIH_SID_KEY]= service_id,476 [UIH_INDEX_KEY]= index,429 430 idx_key_t idx_key = { 431 .service_id = service_id, 432 .index = index, 477 433 }; 478 434 479 435 fibril_mutex_lock(&used_lock); 480 l = hash_table_find(&ui_hash, ikey);436 ht_link_t *l = hash_table_find(&ui_hash, &idx_key); 481 437 if (l) { 482 fidx = hash_table_get_inst ance(l, exfat_idx_t, uih_link);438 fidx = hash_table_get_inst(l, exfat_idx_t, uih_link); 483 439 fibril_mutex_lock(&fidx->lock); 484 440 } … … 494 450 void exfat_idx_destroy(exfat_idx_t *idx) 495 451 { 496 unsigned long ikey[]= {497 [UIH_SID_KEY]= idx->service_id,498 [UIH_INDEX_KEY]= idx->index,452 idx_key_t idx_key = { 453 .service_id = idx->service_id, 454 .index = idx->index, 499 455 }; 500 service_id_t service_id = idx->service_id;501 fs_index_t index = idx->index;502 456 503 457 /* TODO: assert(idx->pfc == FAT_CLST_RES0); */ … … 510 464 * the index hash only. 511 465 */ 512 hash_table_remove(&ui_hash, ikey, 2);466 hash_table_remove(&ui_hash, &idx_key); 513 467 fibril_mutex_unlock(&used_lock); 514 468 /* Release the VFS index. */ 515 exfat_index_free( service_id,index);469 exfat_index_free(idx_key.service_id, idx_key.index); 516 470 /* The index structure itself is freed in idx_remove_callback(). */ 517 471 } … … 519 473 int exfat_idx_init(void) 520 474 { 521 if (!hash_table_create(&up_hash, 0, 3, &uph_ops))475 if (!hash_table_create(&up_hash, 0, 0, &uph_ops)) 522 476 return ENOMEM; 523 if (!hash_table_create(&ui_hash, 0, 2, &uih_ops)) {477 if (!hash_table_create(&ui_hash, 0, 0, &uih_ops)) { 524 478 hash_table_destroy(&up_hash); 525 479 return ENOMEM; … … 531 485 { 532 486 /* We assume the hash tables are empty. */ 487 assert(hash_table_empty(&up_hash) && hash_table_empty(&ui_hash)); 533 488 hash_table_destroy(&up_hash); 534 489 hash_table_destroy(&ui_hash); … … 555 510 } 556 511 512 static bool rm_pos_service_id(ht_link_t *item, void *arg) 513 { 514 service_id_t service_id = *(service_id_t*)arg; 515 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link); 516 517 if (fidx->service_id == service_id) { 518 hash_table_remove_item(&up_hash, item); 519 } 520 521 return true; 522 } 523 524 static bool rm_idx_service_id(ht_link_t *item, void *arg) 525 { 526 service_id_t service_id = *(service_id_t*)arg; 527 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); 528 529 if (fidx->service_id == service_id) { 530 hash_table_remove_item(&ui_hash, item); 531 } 532 533 return true; 534 } 535 557 536 void exfat_idx_fini_by_service_id(service_id_t service_id) 558 537 { 559 unsigned long ikey[] = {560 [UIH_SID_KEY] = service_id561 };562 unsigned long pkey[] = {563 [UPH_SID_KEY] = service_id564 };565 566 538 /* 567 539 * Remove this instance's index structure from up_hash and ui_hash. … … 570 542 */ 571 543 fibril_mutex_lock(&used_lock); 572 hash_table_ remove(&up_hash, pkey, 1);573 hash_table_ remove(&ui_hash, ikey, 1);544 hash_table_apply(&up_hash, rm_pos_service_id, &service_id); 545 hash_table_apply(&ui_hash, rm_idx_service_id, &service_id); 574 546 fibril_mutex_unlock(&used_lock); 575 547 -
uspace/srv/fs/exfat/exfat_ops.c
rb17518e rbc216a0 54 54 #include <byteorder.h> 55 55 #include <adt/hash_table.h> 56 #include <adt/hash.h> 56 57 #include <adt/list.h> 57 58 #include <assert.h> -
uspace/srv/fs/ext2fs/ext2fs_ops.c
rb17518e rbc216a0 49 49 #include <byteorder.h> 50 50 #include <adt/hash_table.h> 51 #include <adt/hash.h> 51 52 #include <adt/list.h> 52 53 #include <assert.h> … … 62 63 #define EXT2FS_NODE(node) ((node) ? (ext2fs_node_t *) (node)->data : NULL) 63 64 #define EXT2FS_DBG(format, ...) {if (false) printf("ext2fs: %s: " format "\n", __FUNCTION__, ##__VA_ARGS__);} 64 #define OPEN_NODES_KEYS 265 #define OPEN_NODES_DEV_HANDLE_KEY 066 #define OPEN_NODES_INODE_KEY 167 65 68 66 typedef struct ext2fs_instance { … … 77 75 ext2_inode_ref_t *inode_ref; 78 76 fs_node_t *fs_node; 79 link_t link;77 ht_link_t link; 80 78 unsigned int references; 81 79 } ext2fs_node_t; … … 121 119 static FIBRIL_MUTEX_INITIALIZE(open_nodes_lock); 122 120 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 125 typedef struct { 126 service_id_t service_id; 127 fs_index_t index; 128 } node_key_t; 129 130 static 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 136 static 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); 136 139 137 140 assert(enode->instance); 138 141 assert(enode->inode_ref); 139 142 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 146 static 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; 162 153 } 163 154 … … 165 156 .hash = open_nodes_hash, 166 157 .key_hash = open_nodes_key_hash, 167 . match = open_nodes_match,158 .key_equal = open_nodes_key_equal, 168 159 .equal = 0, 169 160 .remove_callback = 0, … … 175 166 int ext2fs_global_init(void) 176 167 { 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)) { 178 169 return ENOMEM; 179 170 } … … 329 320 330 321 /* 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 334 325 }; 335 link_t *already_open = hash_table_find(&open_nodes,key);326 ht_link_t *already_open = hash_table_find(&open_nodes, &key); 336 327 337 328 if (already_open) { 338 enode = hash_table_get_inst ance(already_open, ext2fs_node_t, link);329 enode = hash_table_get_inst(already_open, ext2fs_node_t, link); 339 330 *rfn = enode->fs_node; 340 331 enode->references++; … … 370 361 enode->references = 1; 371 362 enode->fs_node = node; 372 link_initialize(&enode->link);373 363 374 364 node->data = enode; … … 421 411 int ext2fs_node_put_core(ext2fs_node_t *enode) 422 412 { 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 428 416 }; 429 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 417 418 hash_table_remove(&open_nodes, &key); 419 430 420 assert(enode->instance->open_nodes_count > 0); 431 421 enode->instance->open_nodes_count--; 432 422 433 rc = ext2_filesystem_put_inode_ref(enode->inode_ref);423 int rc = ext2_filesystem_put_inode_ref(enode->inode_ref); 434 424 if (rc != EOK) { 435 425 EXT2FS_DBG("ext2_filesystem_put_inode_ref failed"); -
uspace/srv/fs/fat/fat.h
rb17518e rbc216a0 190 190 typedef struct { 191 191 /** Used indices (position) hash table link. */ 192 link_t uph_link;192 ht_link_t uph_link; 193 193 /** Used indices (index) hash table link. */ 194 link_t uih_link;194 ht_link_t uih_link; 195 195 196 196 fibril_mutex_t lock; -
uspace/srv/fs/fat/fat_idx.c
rb17518e rbc216a0 41 41 #include <str.h> 42 42 #include <adt/hash_table.h> 43 #include <adt/hash.h> 43 44 #include <adt/list.h> 44 45 #include <assert.h> 45 46 #include <fibril_synch.h> 46 47 #include <malloc.h> 47 48 48 49 49 /** Each instance of this type describes one interval of freed VFS indices. */ … … 59 59 */ 60 60 typedef struct { 61 link_t 62 service_id_t 61 link_t link; 62 service_id_t service_id; 63 63 64 64 /** Next unassigned index. */ … … 98 98 return u; 99 99 } 100 100 101 101 if (lock) 102 102 fibril_mutex_unlock(&unused_lock); … … 114 114 static hash_table_t up_hash; 115 115 116 #define UPH_SID_KEY 0 117 #define UPH_PFC_KEY 1 118 #define UPH_PDI_KEY 2 119 120 static size_t pos_key_hash(unsigned long key[]) 121 { 122 /* Inspired by Effective Java, 2nd edition. */ 123 size_t hash = 17; 124 125 hash = 31 * hash + key[UPH_PFC_KEY]; 126 hash = 31 * hash + key[UPH_PDI_KEY]; 127 hash = 31 * hash + key[UPH_SID_KEY]; 128 129 return hash; 130 } 131 132 static size_t pos_hash(const link_t *item) 133 { 134 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link); 135 136 unsigned long pkey[] = { 137 [UPH_SID_KEY] = fidx->service_id, 138 [UPH_PFC_KEY] = fidx->pfc, 139 [UPH_PDI_KEY] = fidx->pdi, 140 }; 141 142 return pos_key_hash(pkey); 143 } 144 145 static bool pos_match(unsigned long key[], size_t keys, const link_t *item) 146 { 147 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 116 typedef struct { 117 service_id_t service_id; 148 118 fat_cluster_t pfc; 149 119 unsigned pdi; 150 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link); 151 152 switch (keys) { 153 case 1: 154 return (service_id == fidx->service_id); 155 case 3: 156 pfc = (fat_cluster_t) key[UPH_PFC_KEY]; 157 pdi = (unsigned) key[UPH_PDI_KEY]; 158 return (service_id == fidx->service_id) && (pfc == fidx->pfc) && 159 (pdi == fidx->pdi); 160 default: 161 assert((keys == 1) || (keys == 3)); 162 } 163 164 return 0; 120 } pos_key_t; 121 122 static inline size_t pos_key_hash(void *key) 123 { 124 pos_key_t *pos = (pos_key_t*)key; 125 126 size_t hash = 0; 127 hash = hash_combine(pos->pfc, pos->pdi); 128 return hash_combine(hash, pos->service_id); 129 } 130 131 static size_t pos_hash(const ht_link_t *item) 132 { 133 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 134 135 pos_key_t pkey = { 136 .service_id = fidx->service_id, 137 .pfc = fidx->pfc, 138 .pdi = fidx->pdi, 139 }; 140 141 return pos_key_hash(&pkey); 142 } 143 144 static bool pos_key_equal(void *key, const ht_link_t *item) 145 { 146 pos_key_t *pos = (pos_key_t*)key; 147 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 148 149 return pos->service_id == fidx->service_id 150 && pos->pdi == fidx->pdi 151 && pos->pfc == fidx->pfc; 165 152 } 166 153 … … 168 155 .hash = pos_hash, 169 156 .key_hash = pos_key_hash, 170 . match = pos_match,157 .key_equal = pos_key_equal, 171 158 .equal = 0, 172 159 .remove_callback = 0, … … 179 166 static hash_table_t ui_hash; 180 167 181 #define UIH_SID_KEY 0 182 #define UIH_INDEX_KEY 1 183 184 static size_t idx_key_hash(unsigned long key[]) 185 { 186 /* 187 * Compute a simple hash unlimited by specific table size as per: 188 * Effective Java, 2nd edition. 189 */ 190 size_t hash = 17; 191 hash = 31 * hash + key[UIH_SID_KEY]; 192 hash = 31 * hash + key[UIH_INDEX_KEY]; 193 return hash; 194 } 195 196 static size_t idx_hash(const link_t *item) 197 { 198 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 199 200 unsigned long ikey[] = { 201 [UIH_SID_KEY] = fidx->service_id, 202 [UIH_INDEX_KEY] = fidx->index, 203 }; 204 205 return idx_key_hash(ikey); 206 } 207 208 static bool idx_match(unsigned long key[], size_t keys, const link_t *item) 209 { 210 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 168 typedef struct { 169 service_id_t service_id; 211 170 fs_index_t index; 212 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 213 214 switch (keys) { 215 case 1: 216 return (service_id == fidx->service_id); 217 case 2: 218 index = (fs_index_t) key[UIH_INDEX_KEY]; 219 return (service_id == fidx->service_id) && 220 (index == fidx->index); 221 default: 222 assert((keys == 1) || (keys == 2)); 223 } 224 225 return 0; 226 } 227 228 static void idx_remove_callback(link_t *item) 229 { 230 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 171 } idx_key_t; 172 173 static size_t idx_key_hash(void *key_arg) 174 { 175 idx_key_t *key = (idx_key_t*)key_arg; 176 return hash_combine(key->service_id, key->index); 177 } 178 179 static size_t idx_hash(const ht_link_t *item) 180 { 181 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 182 return hash_combine(fidx->service_id, fidx->index); 183 } 184 185 static bool idx_key_equal(void *key_arg, const ht_link_t *item) 186 { 187 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 188 idx_key_t *key = (idx_key_t*)key_arg; 189 190 return key->index == fidx->index && key->service_id == fidx->service_id; 191 } 192 193 static void idx_remove_callback(ht_link_t *item) 194 { 195 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 231 196 232 197 free(fidx); … … 236 201 .hash = idx_hash, 237 202 .key_hash = idx_key_hash, 238 . match = idx_match,203 .key_equal = idx_key_equal, 239 204 .equal = 0, 240 205 .remove_callback = idx_remove_callback, … … 378 343 } 379 344 380 link_initialize(&fidx->uph_link);381 link_initialize(&fidx->uih_link);382 345 fibril_mutex_initialize(&fidx->lock); 383 346 fidx->service_id = service_id; … … 414 377 { 415 378 fat_idx_t *fidx; 416 link_t *l; 417 unsigned long pkey[]= {418 [UPH_SID_KEY]= service_id,419 [UPH_PFC_KEY]= pfc,420 [UPH_PDI_KEY]= pdi,379 380 pos_key_t pos_key = { 381 .service_id = service_id, 382 .pfc = pfc, 383 .pdi = pdi, 421 384 }; 422 385 423 386 fibril_mutex_lock(&used_lock); 424 l = hash_table_find(&up_hash, pkey);387 ht_link_t *l = hash_table_find(&up_hash, &pos_key); 425 388 if (l) { 426 fidx = hash_table_get_inst ance(l, fat_idx_t, uph_link);389 fidx = hash_table_get_inst(l, fat_idx_t, uph_link); 427 390 } else { 428 391 int rc; … … 464 427 { 465 428 fat_idx_t *fidx = NULL; 466 link_t *l; 467 unsigned long ikey[]= {468 [UIH_SID_KEY]= service_id,469 [UIH_INDEX_KEY]= index,429 430 idx_key_t idx_key = { 431 .service_id = service_id, 432 .index = index, 470 433 }; 471 434 472 435 fibril_mutex_lock(&used_lock); 473 l = hash_table_find(&ui_hash, ikey);436 ht_link_t *l = hash_table_find(&ui_hash, &idx_key); 474 437 if (l) { 475 fidx = hash_table_get_inst ance(l, fat_idx_t, uih_link);438 fidx = hash_table_get_inst(l, fat_idx_t, uih_link); 476 439 fibril_mutex_lock(&fidx->lock); 477 440 } … … 487 450 void fat_idx_destroy(fat_idx_t *idx) 488 451 { 489 unsigned long ikey[]= {490 [UIH_SID_KEY]= idx->service_id,491 [UIH_INDEX_KEY]= idx->index,452 idx_key_t idx_key = { 453 .service_id = idx->service_id, 454 .index = idx->index, 492 455 }; 493 service_id_t service_id = idx->service_id;494 fs_index_t index = idx->index;495 456 496 457 assert(idx->pfc == FAT_CLST_RES0); … … 502 463 * the index hash only. 503 464 */ 504 hash_table_remove(&ui_hash, ikey, 2);465 hash_table_remove(&ui_hash, &idx_key); 505 466 fibril_mutex_unlock(&used_lock); 506 467 /* Release the VFS index. */ 507 fat_index_free( service_id,index);468 fat_index_free(idx_key.service_id, idx_key.index); 508 469 /* The index structure itself is freed in idx_remove_callback(). */ 509 470 } … … 511 472 int fat_idx_init(void) 512 473 { 513 if (!hash_table_create(&up_hash, 0, 3, &uph_ops))474 if (!hash_table_create(&up_hash, 0, 0, &uph_ops)) 514 475 return ENOMEM; 515 if (!hash_table_create(&ui_hash, 0, 2, &uih_ops)) {476 if (!hash_table_create(&ui_hash, 0, 0, &uih_ops)) { 516 477 hash_table_destroy(&up_hash); 517 478 return ENOMEM; … … 523 484 { 524 485 /* We assume the hash tables are empty. */ 486 assert(hash_table_empty(&up_hash) && hash_table_empty(&ui_hash)); 525 487 hash_table_destroy(&up_hash); 526 488 hash_table_destroy(&ui_hash); … … 547 509 } 548 510 511 static bool rm_pos_service_id(ht_link_t *item, void *arg) 512 { 513 service_id_t service_id = *(service_id_t*)arg; 514 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link); 515 516 if (fidx->service_id == service_id) { 517 hash_table_remove_item(&up_hash, item); 518 } 519 520 return true; 521 } 522 523 static bool rm_idx_service_id(ht_link_t *item, void *arg) 524 { 525 service_id_t service_id = *(service_id_t*)arg; 526 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); 527 528 if (fidx->service_id == service_id) { 529 hash_table_remove_item(&ui_hash, item); 530 } 531 532 return true; 533 } 534 549 535 void fat_idx_fini_by_service_id(service_id_t service_id) 550 536 { 551 unsigned long ikey[] = {552 [UIH_SID_KEY] = service_id553 };554 unsigned long pkey[] = {555 [UPH_SID_KEY] = service_id556 };557 558 537 /* 559 538 * Remove this instance's index structure from up_hash and ui_hash. … … 562 541 */ 563 542 fibril_mutex_lock(&used_lock); 564 hash_table_ remove(&up_hash, pkey, 1);565 hash_table_ remove(&ui_hash, ikey, 1);543 hash_table_apply(&up_hash, rm_pos_service_id, &service_id); 544 hash_table_apply(&ui_hash, rm_idx_service_id, &service_id); 566 545 fibril_mutex_unlock(&used_lock); 567 546 -
uspace/srv/fs/locfs/locfs_ops.c
rb17518e rbc216a0 61 61 async_sess_t *sess; /**< If NULL, the structure is incomplete. */ 62 62 size_t refcount; 63 link_t link;63 ht_link_t link; 64 64 fibril_condvar_t cv; /**< Broadcast when completed. */ 65 65 } service_t; … … 71 71 static FIBRIL_MUTEX_INITIALIZE(services_mutex); 72 72 73 #define SERVICES_KEYS 174 #define SERVICES_KEY_HANDLE 075 76 73 /* Implementation of hash table interface for the nodes hash table. */ 77 74 78 static size_t services_key_hash(unsigned long key[]) 79 { 80 return key[SERVICES_KEY_HANDLE]; 81 } 82 83 static size_t services_hash(const link_t *item) 84 { 85 service_t *dev = hash_table_get_instance(item, service_t, link); 86 unsigned long key[] = { 87 [SERVICES_KEY_HANDLE] = dev->service_id 88 }; 89 90 return services_key_hash(key); 91 } 92 93 static bool services_match(unsigned long key[], size_t keys, const link_t *item) 94 { 95 assert(keys == 1); 96 service_t *dev = hash_table_get_instance(item, service_t, link); 97 return (dev->service_id == (service_id_t) key[SERVICES_KEY_HANDLE]); 98 } 99 100 static void services_remove_callback(link_t *item) 101 { 102 free(hash_table_get_instance(item, service_t, link)); 75 static size_t services_key_hash(void *key) 76 { 77 return *(service_id_t*)key; 78 } 79 80 static size_t services_hash(const ht_link_t *item) 81 { 82 service_t *dev = hash_table_get_inst(item, service_t, link); 83 return dev->service_id; 84 } 85 86 static bool services_key_equal(void *key, const ht_link_t *item) 87 { 88 service_t *dev = hash_table_get_inst(item, service_t, link); 89 return (dev->service_id == *(service_id_t*)key); 90 } 91 92 static void services_remove_callback(ht_link_t *item) 93 { 94 free(hash_table_get_inst(item, service_t, link)); 103 95 } 104 96 … … 106 98 .hash = services_hash, 107 99 .key_hash = services_key_hash, 108 . match = services_match,100 .key_equal = services_key_equal, 109 101 .equal = 0, 110 102 .remove_callback = services_remove_callback … … 242 234 /* Device node */ 243 235 244 unsigned long key[] = {245 [SERVICES_KEY_HANDLE] = (unsigned long) node->service_id246 };247 link_t *lnk;248 249 236 fibril_mutex_lock(&services_mutex); 237 ht_link_t *lnk; 250 238 restart: 251 lnk = hash_table_find(&services, key);239 lnk = hash_table_find(&services, &node->service_id); 252 240 if (lnk == NULL) { 253 241 service_t *dev = (service_t *) malloc(sizeof(service_t)); … … 292 280 * entry and free the device structure. 293 281 */ 294 hash_table_remove(&services, key, SERVICES_KEYS);282 hash_table_remove(&services, &node->service_id); 295 283 fibril_mutex_unlock(&services_mutex); 296 284 … … 301 289 dev->sess = sess; 302 290 } else { 303 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);291 service_t *dev = hash_table_get_inst(lnk, service_t, link); 304 292 305 293 if (!dev->sess) { … … 463 451 bool locfs_init(void) 464 452 { 465 if (!hash_table_create(&services, 0, SERVICES_KEYS, &services_ops))453 if (!hash_table_create(&services, 0, 0, &services_ops)) 466 454 return false; 467 455 … … 567 555 /* Device node */ 568 556 569 unsigned long key[] = {570 [SERVICES_KEY_HANDLE] = (unsigned long) index571 };572 573 557 fibril_mutex_lock(&services_mutex); 574 link_t *lnk = hash_table_find(&services, key);558 ht_link_t *lnk = hash_table_find(&services, &index); 575 559 if (lnk == NULL) { 576 560 fibril_mutex_unlock(&services_mutex); … … 578 562 } 579 563 580 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);564 service_t *dev = hash_table_get_inst(lnk, service_t, link); 581 565 assert(dev->sess); 582 566 … … 633 617 if (type == LOC_OBJECT_SERVICE) { 634 618 /* Device node */ 635 unsigned long key[] = {636 [SERVICES_KEY_HANDLE] = (unsigned long) index637 };638 619 639 620 fibril_mutex_lock(&services_mutex); 640 link_t *lnk = hash_table_find(&services, key);621 ht_link_t *lnk = hash_table_find(&services, &index); 641 622 if (lnk == NULL) { 642 623 fibril_mutex_unlock(&services_mutex); … … 644 625 } 645 626 646 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);627 service_t *dev = hash_table_get_inst(lnk, service_t, link); 647 628 assert(dev->sess); 648 629 … … 703 684 704 685 if (type == LOC_OBJECT_SERVICE) { 705 unsigned long key[] = {706 [SERVICES_KEY_HANDLE] = (unsigned long) index707 };708 686 709 687 fibril_mutex_lock(&services_mutex); 710 link_t *lnk = hash_table_find(&services, key);688 ht_link_t *lnk = hash_table_find(&services, &index); 711 689 if (lnk == NULL) { 712 690 fibril_mutex_unlock(&services_mutex); … … 714 692 } 715 693 716 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);694 service_t *dev = hash_table_get_inst(lnk, service_t, link); 717 695 assert(dev->sess); 718 696 dev->refcount--; … … 720 698 if (dev->refcount == 0) { 721 699 async_hangup(dev->sess); 722 hash_table_remove(&services, key, SERVICES_KEYS);700 hash_table_remove(&services, &index); 723 701 } 724 702 … … 744 722 745 723 if (type == LOC_OBJECT_SERVICE) { 746 unsigned long key[] = { 747 [SERVICES_KEY_HANDLE] = (unsigned long) index 748 }; 749 724 750 725 fibril_mutex_lock(&services_mutex); 751 link_t *lnk = hash_table_find(&services, key);726 ht_link_t *lnk = hash_table_find(&services, &index); 752 727 if (lnk == NULL) { 753 728 fibril_mutex_unlock(&services_mutex); … … 755 730 } 756 731 757 service_t *dev = hash_table_get_inst ance(lnk, service_t, link);732 service_t *dev = hash_table_get_inst(lnk, service_t, link); 758 733 assert(dev->sess); 759 734 -
uspace/srv/fs/mfs/mfs.h
rb17518e rbc216a0 142 142 unsigned refcnt; 143 143 fs_node_t *fsnode; 144 link_t link;144 ht_link_t link; 145 145 }; 146 146 -
uspace/srv/fs/mfs/mfs_ops.c
rb17518e rbc216a0 35 35 #include <align.h> 36 36 #include <adt/hash_table.h> 37 #include <adt/hash.h> 37 38 #include "mfs.h" 38 39 39 #define OPEN_NODES_KEYS 240 #define OPEN_NODES_SERVICE_KEY 041 #define OPEN_NODES_INODE_KEY 142 40 43 41 static bool check_magic_number(uint16_t magic, bool *native, … … 60 58 static int mfs_unlink(fs_node_t *, fs_node_t *, const char *name); 61 59 static int mfs_destroy_node(fs_node_t *fn); 62 static size_t open_nodes_hash(const link_t *item);63 static size_t open_nodes_key_hash(unsigned long key[]);64 static bool open_nodes_match(unsigned long key[], size_t keys,65 const link_t *item);66 60 static int mfs_node_get(fs_node_t **rfn, service_id_t service_id, 67 61 fs_index_t index); … … 95 89 /* Hash table interface for open nodes hash table */ 96 90 91 typedef struct { 92 service_id_t service_id; 93 fs_index_t index; 94 } node_key_t; 95 97 96 static size_t 98 open_nodes_key_hash(unsigned long key[]) 99 { 100 /* As recommended by Effective Java, 2nd Edition. */ 101 size_t hash = 17; 102 hash = 37 * hash + key[OPEN_NODES_SERVICE_KEY]; 103 hash = 37 * hash + key[OPEN_NODES_INODE_KEY]; 104 return hash; 97 open_nodes_key_hash(void *key) 98 { 99 node_key_t *node_key = (node_key_t*)key; 100 return hash_combine(node_key->service_id, node_key->index); 105 101 } 106 102 107 103 static size_t 108 open_nodes_hash(const link_t *item) 109 { 110 struct mfs_node *m = hash_table_get_instance(item, struct mfs_node, link); 111 112 unsigned long key[] = { 113 [OPEN_NODES_SERVICE_KEY] = m->instance->service_id, 114 [OPEN_NODES_INODE_KEY] = m->ino_i->index, 115 }; 116 117 return open_nodes_key_hash(key); 104 open_nodes_hash(const ht_link_t *item) 105 { 106 struct mfs_node *m = hash_table_get_inst(item, struct mfs_node, link); 107 return hash_combine(m->instance->service_id, m->ino_i->index); 118 108 } 119 109 120 110 static bool 121 open_nodes_match(unsigned long key[], size_t keys, const link_t *item) 122 { 123 assert(keys == 2); 124 struct mfs_node *mnode = hash_table_get_instance(item, struct mfs_node, link); 125 126 service_id_t service_id = ((service_id_t) key[OPEN_NODES_SERVICE_KEY]); 127 128 return mnode->instance->service_id == service_id 129 && mnode->ino_i->index == key[OPEN_NODES_INODE_KEY]; 130 } 131 111 open_nodes_key_equal(void *key, const ht_link_t *item) 112 { 113 node_key_t *node_key = (node_key_t*)key; 114 struct mfs_node *mnode = hash_table_get_inst(item, struct mfs_node, link); 115 116 return node_key->service_id == mnode->instance->service_id 117 && node_key->index == mnode->ino_i->index; 118 } 132 119 133 120 static hash_table_ops_t open_nodes_ops = { 134 121 .hash = open_nodes_hash, 135 122 .key_hash = open_nodes_key_hash, 136 . match = open_nodes_match,123 .key_equal = open_nodes_key_equal, 137 124 .equal = 0, 138 125 .remove_callback = 0, … … 142 129 mfs_global_init(void) 143 130 { 144 if (!hash_table_create(&open_nodes, 0, OPEN_NODES_KEYS, &open_nodes_ops)) {131 if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) { 145 132 return ENOMEM; 146 133 } … … 413 400 mnode->refcnt = 1; 414 401 415 link_initialize(&mnode->link);416 417 402 fibril_mutex_lock(&open_nodes_lock); 418 403 hash_table_insert(&open_nodes, &mnode->link); … … 515 500 mnode->refcnt--; 516 501 if (mnode->refcnt == 0) { 517 unsigned long key[] = { 518 [OPEN_NODES_SERVICE_KEY] = mnode->instance->service_id, 519 [OPEN_NODES_INODE_KEY] = mnode->ino_i->index 520 }; 521 hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS); 502 hash_table_remove_item(&open_nodes, &mnode->link); 522 503 assert(mnode->instance->open_nodes_cnt > 0); 523 504 mnode->instance->open_nodes_cnt--; … … 578 559 579 560 /* Check if the node is not already open */ 580 unsigned long key[]= {581 [OPEN_NODES_SERVICE_KEY]= inst->service_id,582 [OPEN_NODES_INODE_KEY] = index,561 node_key_t key = { 562 .service_id = inst->service_id, 563 .index = index 583 564 }; 584 link_t *already_open = hash_table_find(&open_nodes, key); 565 566 ht_link_t *already_open = hash_table_find(&open_nodes, &key); 585 567 586 568 if (already_open) { 587 mnode = hash_table_get_inst ance(already_open, struct mfs_node, link);569 mnode = hash_table_get_inst(already_open, struct mfs_node, link); 588 570 *rfn = mnode->fsnode; 589 571 mnode->refcnt++; … … 616 598 mnode->ino_i = ino_i; 617 599 mnode->refcnt = 1; 618 link_initialize(&mnode->link);619 600 620 601 mnode->instance = inst; -
uspace/srv/fs/tmpfs/tmpfs.h
rb17518e rbc216a0 62 62 fs_index_t index; /**< TMPFS node index. */ 63 63 service_id_t service_id;/**< Service ID of block device. */ 64 link_t nh_link; /**< Nodes hash table link. */64 ht_link_t nh_link; /**< Nodes hash table link. */ 65 65 tmpfs_dentry_type_t type; 66 66 unsigned lnkcnt; /**< Link count. */ -
uspace/srv/fs/tmpfs/tmpfs_ops.c
rb17518e rbc216a0 50 50 #include <sys/types.h> 51 51 #include <adt/hash_table.h> 52 #include <adt/hash.h> 52 53 #include <as.h> 53 54 #include <libfs.h> … … 140 141 hash_table_t nodes; 141 142 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 147 typedef struct { 148 service_id_t service_id; 149 fs_index_t index; 150 } node_key_t; 151 152 static 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 158 static 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 164 static 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 172 static void nodes_remove_callback(ht_link_t *item) 173 { 174 tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link); 189 175 190 176 while (!list_empty(&nodep->cs_list)) { … … 209 195 .hash = nodes_hash, 210 196 .key_hash = nodes_key_hash, 211 . match = nodes_match,197 .key_equal = nodes_key_equal, 212 198 .equal = 0, 213 199 .remove_callback = nodes_remove_callback … … 223 209 nodep->size = 0; 224 210 nodep->data = NULL; 225 link_initialize(&nodep->nh_link);226 211 list_initialize(&nodep->cs_list); 227 212 } … … 236 221 bool tmpfs_init(void) 237 222 { 238 if (!hash_table_create(&nodes, 0, 2, &nodes_ops))223 if (!hash_table_create(&nodes, 0, 0, &nodes_ops)) 239 224 return false; 240 225 … … 254 239 } 255 240 241 static 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 256 252 static 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); 269 255 } 270 256 … … 288 274 int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index) 289 275 { 290 unsigned long key[]= {291 [NODES_KEY_DEV]= service_id,292 [NODES_KEY_INDEX]= index276 node_key_t key = { 277 .service_id = service_id, 278 .index = index 293 279 }; 294 link_t *lnk = hash_table_find(&nodes, key); 280 281 ht_link_t *lnk = hash_table_find(&nodes, &key); 282 295 283 if (lnk) { 296 284 tmpfs_node_t *nodep; 297 nodep = hash_table_get_inst ance(lnk, tmpfs_node_t, nh_link);285 nodep = hash_table_get_inst(lnk, tmpfs_node_t, nh_link); 298 286 *rfn = FS_NODE(nodep); 299 287 } else { … … 358 346 assert(!nodep->lnkcnt); 359 347 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); 366 350 367 351 /* … … 488 472 * Lookup the respective TMPFS node. 489 473 */ 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 494 477 }; 495 hlp = hash_table_find(&nodes, key); 478 479 ht_link_t *hlp = hash_table_find(&nodes, &key); 496 480 if (!hlp) 497 481 return ENOENT; 498 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,499 482 483 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 500 484 501 485 /* … … 550 534 * Lookup the respective TMPFS node. 551 535 */ 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 556 539 }; 557 hlp = hash_table_find(&nodes, key); 540 541 ht_link_t *hlp = hash_table_find(&nodes, &key); 542 558 543 if (!hlp) 559 544 return ENOENT; 560 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,561 545 546 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 562 547 563 548 /* … … 612 597 * Lookup the respective TMPFS node. 613 598 */ 614 unsigned long key[]= {615 [NODES_KEY_DEV]= service_id,616 [NODES_KEY_INDEX]= index599 node_key_t key = { 600 .service_id = service_id, 601 .index = index 617 602 }; 618 link_t *hlp = hash_table_find(&nodes, key); 603 604 ht_link_t *hlp = hash_table_find(&nodes, &key); 605 619 606 if (!hlp) 620 607 return ENOENT; 621 tmpfs_node_t *nodep = hash_table_get_inst ance(hlp, tmpfs_node_t, nh_link);608 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link); 622 609 623 610 if (size == nodep->size) … … 648 635 static int tmpfs_destroy(service_id_t service_id, fs_index_t index) 649 636 { 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 654 640 }; 655 hlp = hash_table_find(&nodes, key); 641 642 ht_link_t *hlp = hash_table_find(&nodes, &key); 656 643 if (!hlp) 657 644 return ENOENT; 658 tmpfs_node_t *nodep = hash_table_get_inst ance(hlp, tmpfs_node_t,645 tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, 659 646 nh_link); 660 647 return tmpfs_destroy_node(FS_NODE(nodep)); -
uspace/srv/hid/input/generic/gsp.c
rb17518e rbc216a0 51 51 #include <gsp.h> 52 52 #include <adt/hash_table.h> 53 #include <adt/hash.h> 53 54 #include <stdlib.h> 54 55 #include <stdio.h> 55 56 56 57 /* 57 * Hash table operations for the transition function. 58 */ 59 60 static size_t trans_op_hash(const link_t *item); 61 static size_t trans_op_key_hash(unsigned long key[]); 62 static bool trans_op_match(unsigned long key[], size_t keys, const link_t *item); 58 * Transition function hash table operations. 59 */ 60 typedef struct { 61 int old_state; 62 int input; 63 } trans_key_t; 64 65 static size_t trans_key_hash(void *key) 66 { 67 trans_key_t *trans_key = (trans_key_t *)key; 68 return hash_combine(trans_key->input, trans_key->old_state); 69 } 70 71 static size_t trans_hash(const ht_link_t *item) 72 { 73 gsp_trans_t *t = hash_table_get_inst(item, gsp_trans_t, link); 74 return hash_combine(t->input, t->old_state); 75 } 76 77 static bool trans_key_equal(void *key, const ht_link_t *item) 78 { 79 trans_key_t *trans_key = (trans_key_t *)key; 80 gsp_trans_t *t = hash_table_get_inst(item, gsp_trans_t, link); 81 82 return trans_key->input == t->input && trans_key->old_state == t->old_state; 83 } 63 84 64 85 static hash_table_ops_t trans_ops = { 65 .hash = trans_ op_hash,66 .key_hash = trans_ op_key_hash,67 . match = trans_op_match,86 .hash = trans_hash, 87 .key_hash = trans_key_hash, 88 .key_equal = trans_key_equal, 68 89 .equal = 0, 69 90 .remove_callback = 0 70 91 }; 71 92 93 72 94 static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input); 73 95 static void trans_insert(gsp_t *p, gsp_trans_t *t); … … 78 100 { 79 101 p->states = 1; 80 hash_table_create(&p->trans, 0, 2, &trans_ops);102 hash_table_create(&p->trans, 0, 0, &trans_ops); 81 103 } 82 104 … … 222 244 static gsp_trans_t *trans_lookup(gsp_t *p, int state, int input) 223 245 { 224 link_t *item; 225 unsigned long key[2]; 226 227 key[0] = state; 228 key[1] = input; 229 230 item = hash_table_find(&p->trans, key); 246 ht_link_t *item; 247 248 trans_key_t key = { 249 .input = input, 250 .old_state = state 251 }; 252 253 item = hash_table_find(&p->trans, &key); 231 254 if (item == NULL) return NULL; 232 255 233 return hash_table_get_inst ance(item, gsp_trans_t, link);256 return hash_table_get_inst(item, gsp_trans_t, link); 234 257 } 235 258 … … 258 281 } 259 282 260 /*261 * Transition function hash table operations.262 */263 264 static size_t trans_op_key_hash(unsigned long key[])265 {266 return (key[0] * 17 + key[1]);267 }268 269 static size_t trans_op_hash(const link_t *item)270 {271 gsp_trans_t *t = hash_table_get_instance(item, gsp_trans_t, link);272 unsigned long key[] = {273 t->old_state,274 t->input275 };276 277 return trans_op_key_hash(key);278 }279 280 static bool trans_op_match(unsigned long key[], size_t keys, const link_t *item)281 {282 gsp_trans_t *t = hash_table_get_instance(item, gsp_trans_t, link);283 return ((key[0] == (unsigned long) t->old_state)284 && (key[1] == (unsigned long) t->input));285 }286 283 287 284 /** -
uspace/srv/hid/input/include/gsp.h
rb17518e rbc216a0 56 56 /** Scancode parser transition. */ 57 57 typedef struct { 58 link_t link; /**< Link to hash table in @c gsp_t */58 ht_link_t link; /**< Link to hash table in @c gsp_t */ 59 59 60 60 /* Preconditions */ -
uspace/srv/ns/service.c
rb17518e rbc216a0 43 43 /** Service hash table item. */ 44 44 typedef struct { 45 link_t link;45 ht_link_t link; 46 46 sysarg_t service; /**< Service ID. */ 47 47 sysarg_t phone; /**< Phone registered with the service. */ … … 49 49 } hashed_service_t; 50 50 51 /** Compute hash index into service hash table. 52 * 53 * @param key Pointer keys. However, only the first key (i.e. service number) 54 * is used to compute the hash index. 55 * 56 * @return Hash index corresponding to key[0]. 57 * 58 */ 59 static size_t service_key_hash(unsigned long key[]) 51 52 static size_t service_key_hash(void *key) 60 53 { 61 assert(key); 62 return key[0]; 54 return *(sysarg_t*)key; 63 55 } 64 56 65 static size_t service_hash(const link_t *item)57 static size_t service_hash(const ht_link_t *item) 66 58 { 67 hashed_service_t *hs = hash_table_get_instance(item, hashed_service_t, link); 68 unsigned long key = hs->service; 69 return service_key_hash(&key); 59 hashed_service_t *hs = hash_table_get_inst(item, hashed_service_t, link); 60 return hs->service; 70 61 } 71 62 72 /** Compare a key with hashed item. 73 * 74 * This compare function always ignores the third key. 75 * It exists only to make it possible to remove records 76 * originating from connection with key[1] in_phone_hash 77 * value. Note that this is close to being classified 78 * as a nasty hack. 79 * 80 * @param key Array of keys. 81 * @param keys Must be lesser or equal to 3. 82 * @param item Pointer to a hash table item. 83 * 84 * @return Non-zero if the key matches the item, zero otherwise. 85 * 86 */ 87 static bool service_match(unsigned long key[], size_t keys, const link_t *item) 63 static bool service_key_equal(void *key, const ht_link_t *item) 88 64 { 89 assert(key); 90 assert(keys <= 3); 91 assert(item); 92 93 hashed_service_t *hs = hash_table_get_instance(item, hashed_service_t, link); 94 95 if (keys == 2) 96 return ((key[0] == hs->service) && (key[1] == hs->in_phone_hash)); 97 else 98 return (key[0] == hs->service); 99 } 100 101 /** Perform actions after removal of item from the hash table. 102 * 103 * @param item Item that was removed from the hash table. 104 * 105 */ 106 static void service_remove(link_t *item) 107 { 108 assert(item); 109 free(hash_table_get_instance(item, hashed_service_t, link)); 65 hashed_service_t *hs = hash_table_get_inst(item, hashed_service_t, link); 66 return hs->service == *(sysarg_t*)key; 110 67 } 111 68 … … 114 71 .hash = service_hash, 115 72 .key_hash = service_key_hash, 116 . match = service_match,73 .key_equal = service_key_equal, 117 74 .equal = 0, 118 .remove_callback = service_remove75 .remove_callback = 0 119 76 }; 120 77 … … 135 92 int service_init(void) 136 93 { 137 if (!hash_table_create(&service_hash_table, 0, 3, &service_hash_table_ops)) {94 if (!hash_table_create(&service_hash_table, 0, 0, &service_hash_table_ops)) { 138 95 printf(NAME ": No memory available for services\n"); 139 96 return ENOMEM; … … 152 109 pending_conn_t *pr = list_get_instance(cur, pending_conn_t, link); 153 110 154 unsigned long keys[3] = { 155 pr->service, 156 0, 157 0 158 }; 159 160 link_t *link = hash_table_find(&service_hash_table, keys); 111 ht_link_t *link = hash_table_find(&service_hash_table, &pr->service); 161 112 if (!link) 162 113 continue; 163 114 164 hashed_service_t *hs = hash_table_get_inst ance(link, hashed_service_t, link);115 hashed_service_t *hs = hash_table_get_inst(link, hashed_service_t, link); 165 116 (void) ipc_forward_fast(pr->callid, hs->phone, pr->arg2, 166 117 pr->arg3, 0, IPC_FF_NONE); … … 183 134 int register_service(sysarg_t service, sysarg_t phone, ipc_call_t *call) 184 135 { 185 unsigned long keys[3] = { 186 service, 187 call->in_phone_hash, 188 0 189 }; 190 191 if (hash_table_find(&service_hash_table, keys)) 136 if (hash_table_find(&service_hash_table, &service)) 192 137 return EEXISTS; 193 138 … … 196 141 return ENOMEM; 197 142 198 link_initialize(&hs->link);199 143 hs->service = service; 200 144 hs->phone = phone; … … 217 161 { 218 162 sysarg_t retval; 219 unsigned long keys[3] = {220 service,221 0,222 0223 };224 163 225 link_t *link = hash_table_find(&service_hash_table, keys);164 ht_link_t *link = hash_table_find(&service_hash_table, &service); 226 165 if (!link) { 227 166 if (IPC_GET_ARG4(*call) & IPC_FLAG_BLOCKING) { … … 246 185 } 247 186 248 hashed_service_t *hs = hash_table_get_inst ance(link, hashed_service_t, link);187 hashed_service_t *hs = hash_table_get_inst(link, hashed_service_t, link); 249 188 (void) ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call), 250 189 IPC_GET_ARG3(*call), 0, IPC_FF_NONE); -
uspace/srv/ns/task.c
rb17518e rbc216a0 53 53 /** Task hash table item. */ 54 54 typedef struct { 55 link_t link;55 ht_link_t link; 56 56 57 57 task_id_t id; /**< Task ID. */ … … 61 61 } hashed_task_t; 62 62 63 /** Compute hash index into task hash table. 64 * 65 * @param key Pointer keys. However, only the first key (i.e. truncated task 66 * number) is used to compute the hash index. 67 * 68 * @return Hash index corresponding to key[0]. 69 * 70 */ 71 static size_t task_key_hash(unsigned long key[]) 72 { 73 size_t hash = 17; 74 hash = 37 * hash + key[1]; 75 hash = 37 * hash + key[0]; 76 return hash; 77 } 78 79 static size_t task_hash(const link_t *item) 80 { 81 hashed_task_t *ht = hash_table_get_instance(item, hashed_task_t, link); 82 83 unsigned long key[] = { 84 LOWER32(ht->id), 85 UPPER32(ht->id) 86 }; 87 88 return task_key_hash(key); 89 } 90 91 /** Compare a key with hashed item. 92 * 93 * @param key Array of keys. 94 * @param keys Must be less than or equal to 2. 95 * @param item Pointer to a hash table item. 96 * 97 * @return Non-zero if the key matches the item, zero otherwise. 98 * 99 */ 100 static bool task_match(unsigned long key[], size_t keys, const link_t *item) 101 { 102 assert(key); 103 assert(keys == 2); 104 assert(item); 105 106 hashed_task_t *ht = hash_table_get_instance(item, hashed_task_t, link); 107 108 return (key[0] == LOWER32(ht->id)) 109 && (key[1] == UPPER32(ht->id)); 110 } 111 112 /** Perform actions after removal of item from the hash table. 113 * 114 * @param item Item that was removed from the hash table. 115 * 116 */ 117 static void task_remove(link_t *item) 118 { 119 assert(item); 120 free(hash_table_get_instance(item, hashed_task_t, link)); 63 64 static size_t task_key_hash(void *key) 65 { 66 return *(task_id_t*)key; 67 } 68 69 static size_t task_hash(const ht_link_t *item) 70 { 71 hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link); 72 return ht->id; 73 } 74 75 static bool task_key_equal(void *key, const ht_link_t *item) 76 { 77 hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link); 78 return ht->id == *(task_id_t*)key; 79 } 80 81 /** Perform actions after removal of item from the hash table. */ 82 static void task_remove(ht_link_t *item) 83 { 84 free(hash_table_get_inst(item, hashed_task_t, link)); 121 85 } 122 86 … … 125 89 .hash = task_hash, 126 90 .key_hash = task_key_hash, 127 . match = task_match,91 .key_equal = task_key_equal, 128 92 .equal = 0, 129 93 .remove_callback = task_remove … … 134 98 135 99 typedef struct { 136 link_t link;100 ht_link_t link; 137 101 sysarg_t in_phone_hash; /**< Incoming phone hash. */ 138 102 task_id_t id; /**< Task ID. */ 139 103 } p2i_entry_t; 140 104 141 /** Compute hash index into task hash table. 142 * 143 * @param key Array of keys. 144 * 145 * @return Hash index corresponding to key[0]. 146 * 147 */ 148 static size_t p2i_key_hash(unsigned long key[]) 149 { 150 assert(key); 151 return key[0]; 152 } 153 154 static size_t p2i_hash(const link_t *item) 155 { 156 p2i_entry_t *entry = hash_table_get_instance(item, p2i_entry_t, link); 157 unsigned long key = entry->in_phone_hash; 158 return p2i_key_hash(&key); 159 } 160 161 /** Compare a key with hashed item. 162 * 163 * @param key Array of keys. 164 * @param keys Must be less than or equal to 1. 165 * @param item Pointer to a hash table item. 166 * 167 * @return Non-zero if the key matches the item, zero otherwise. 168 * 169 */ 170 static bool p2i_match(unsigned long key[], size_t keys, const link_t *item) 171 { 172 assert(key); 173 assert(keys == 1); 105 /* phone-to-id hash table operations */ 106 107 static size_t p2i_key_hash(void *key) 108 { 109 sysarg_t in_phone_hash = *(sysarg_t*)key; 110 return in_phone_hash; 111 } 112 113 static size_t p2i_hash(const ht_link_t *item) 114 { 115 p2i_entry_t *entry = hash_table_get_inst(item, p2i_entry_t, link); 116 return entry->in_phone_hash; 117 } 118 119 static bool p2i_key_equal(void *key, const ht_link_t *item) 120 { 121 sysarg_t in_phone_hash = *(sysarg_t*)key; 122 p2i_entry_t *entry = hash_table_get_inst(item, p2i_entry_t, link); 123 124 return (in_phone_hash == entry->in_phone_hash); 125 } 126 127 /** Perform actions after removal of item from the hash table. 128 * 129 * @param item Item that was removed from the hash table. 130 * 131 */ 132 static void p2i_remove(ht_link_t *item) 133 { 174 134 assert(item); 175 176 p2i_entry_t *entry = hash_table_get_instance(item, p2i_entry_t, link); 177 178 return (key[0] == entry->in_phone_hash); 179 } 180 181 /** Perform actions after removal of item from the hash table. 182 * 183 * @param item Item that was removed from the hash table. 184 * 185 */ 186 static void p2i_remove(link_t *item) 187 { 188 assert(item); 189 free(hash_table_get_instance(item, p2i_entry_t, link)); 135 free(hash_table_get_inst(item, p2i_entry_t, link)); 190 136 } 191 137 … … 194 140 .hash = p2i_hash, 195 141 .key_hash = p2i_key_hash, 196 . match = p2i_match,142 .key_equal = p2i_key_equal, 197 143 .equal = 0, 198 144 .remove_callback = p2i_remove … … 213 159 int task_init(void) 214 160 { 215 if (!hash_table_create(&task_hash_table, 0, 2, &task_hash_table_ops)) {161 if (!hash_table_create(&task_hash_table, 0, 0, &task_hash_table_ops)) { 216 162 printf(NAME ": No memory available for tasks\n"); 217 163 return ENOMEM; 218 164 } 219 165 220 if (!hash_table_create(&phone_to_id, 0, 1, &p2i_ops)) {166 if (!hash_table_create(&phone_to_id, 0, 0, &p2i_ops)) { 221 167 printf(NAME ": No memory available for tasks\n"); 222 168 return ENOMEM; … … 236 182 pending_wait_t *pr = list_get_instance(cur, pending_wait_t, link); 237 183 238 unsigned long keys[2] = { 239 LOWER32(pr->id), 240 UPPER32(pr->id) 241 }; 242 243 link_t *link = hash_table_find(&task_hash_table, keys); 184 ht_link_t *link = hash_table_find(&task_hash_table, &pr->id); 244 185 if (!link) 245 186 continue; 246 187 247 hashed_task_t *ht = hash_table_get_inst ance(link, hashed_task_t, link);188 hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link); 248 189 if (!ht->finished) 249 190 continue; … … 256 197 } 257 198 258 hash_table_remove(&task_hash_table, keys, 2);199 hash_table_remove(&task_hash_table, &pr->id); 259 200 list_remove(cur); 260 201 free(pr); … … 268 209 task_exit_t texit; 269 210 270 unsigned long keys[2] = { 271 LOWER32(id), 272 UPPER32(id) 273 }; 274 275 link_t *link = hash_table_find(&task_hash_table, keys); 211 ht_link_t *link = hash_table_find(&task_hash_table, &id); 276 212 hashed_task_t *ht = (link != NULL) ? 277 hash_table_get_inst ance(link, hashed_task_t, link) : NULL;213 hash_table_get_inst(link, hashed_task_t, link) : NULL; 278 214 279 215 if (ht == NULL) { … … 299 235 } 300 236 301 hash_table_remove (&task_hash_table, keys, 2);237 hash_table_remove_item(&task_hash_table, link); 302 238 retval = EOK; 303 239 … … 314 250 task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call)); 315 251 316 unsigned long keys[] = { call->in_phone_hash }; 317 318 link_t *link = hash_table_find(&phone_to_id, keys); 252 ht_link_t *link = hash_table_find(&phone_to_id, &call->in_phone_hash); 319 253 if (link != NULL) 320 254 return EEXISTS; … … 332 266 */ 333 267 334 link_initialize(&entry->link);335 268 entry->in_phone_hash = call->in_phone_hash; 336 269 entry->id = id; … … 341 274 */ 342 275 343 link_initialize(&ht->link);344 276 ht->id = id; 345 277 ht->finished = false; … … 353 285 static int get_id_by_phone(sysarg_t phone_hash, task_id_t *id) 354 286 { 355 unsigned long keys[1] = {phone_hash}; 356 357 link_t *link = hash_table_find(&phone_to_id, keys); 287 ht_link_t *link = hash_table_find(&phone_to_id, &phone_hash); 358 288 if (link == NULL) 359 289 return ENOENT; 360 290 361 p2i_entry_t *entry = hash_table_get_inst ance(link, p2i_entry_t, link);291 p2i_entry_t *entry = hash_table_get_inst(link, p2i_entry_t, link); 362 292 *id = entry->id; 363 293 … … 372 302 return rc; 373 303 374 unsigned long keys[2] = { 375 LOWER32(id), 376 UPPER32(id) 377 }; 378 379 link_t *link = hash_table_find(&task_hash_table, keys); 304 ht_link_t *link = hash_table_find(&task_hash_table, &id); 380 305 hashed_task_t *ht = (link != NULL) ? 381 hash_table_get_inst ance(link, hashed_task_t, link) : NULL;306 hash_table_get_inst(link, hashed_task_t, link) : NULL; 382 307 383 308 if ((ht == NULL) || (ht->finished)) … … 393 318 int ns_task_disconnect(ipc_call_t *call) 394 319 { 395 unsigned long keys[2];396 397 320 task_id_t id; 398 321 int rc = get_id_by_phone(call->in_phone_hash, &id); … … 401 324 402 325 /* Delete from phone-to-id map. */ 403 keys[0] = call->in_phone_hash; 404 hash_table_remove(&phone_to_id, keys, 1); 326 hash_table_remove(&phone_to_id, &call->in_phone_hash); 405 327 406 328 /* Mark task as finished. */ 407 keys[0] = LOWER32(id); 408 keys[1] = UPPER32(id); 409 410 link_t *link = hash_table_find(&task_hash_table, keys); 329 ht_link_t *link = hash_table_find(&task_hash_table, &id); 411 330 if (link == NULL) 412 331 return EOK; 413 332 414 hashed_task_t *ht = 415 hash_table_get_instance(link, hashed_task_t, link); 333 hashed_task_t *ht = hash_table_get_inst(link, hashed_task_t, link); 416 334 417 335 ht->finished = true; -
uspace/srv/vfs/vfs.h
rb17518e rbc216a0 36 36 #include <async.h> 37 37 #include <adt/list.h> 38 #include <adt/hash_table.h> 38 39 #include <fibril_synch.h> 39 40 #include <sys/types.h> … … 112 113 unsigned lnkcnt; 113 114 114 link_t nh_link; /**< Node hash-table link. */115 ht_link_t nh_link; /**< Node hash-table link. */ 115 116 116 117 vfs_node_type_t type; /**< Partial info about the node type. */ -
uspace/srv/vfs/vfs_node.c
rb17518e rbc216a0 41 41 #include <fibril_synch.h> 42 42 #include <adt/hash_table.h> 43 #include <adt/hash.h> 43 44 #include <assert.h> 44 45 #include <async.h> … … 58 59 #define KEY_INDEX 2 59 60 60 static size_t nodes_key_hash(unsigned long []); 61 static size_t nodes_hash(const link_t *); 62 static bool nodes_match(unsigned long [], size_t, const link_t *); 61 static size_t nodes_key_hash(void *); 62 static size_t nodes_hash(const ht_link_t *); 63 static bool nodes_key_equal(void *, const ht_link_t *); 64 static vfs_triplet_t node_triplet(vfs_node_t *node); 63 65 64 66 /** VFS node hash table operations. */ … … 66 68 .hash = nodes_hash, 67 69 .key_hash = nodes_key_hash, 68 . match = nodes_match,70 .key_equal = nodes_key_equal, 69 71 .equal = 0, 70 72 .remove_callback = 0, … … 77 79 bool vfs_nodes_init(void) 78 80 { 79 return hash_table_create(&nodes, 0, 3, &nodes_ops);81 return hash_table_create(&nodes, 0, 0, &nodes_ops); 80 82 } 81 83 … … 116 118 */ 117 119 118 unsigned long key[] = { 119 [KEY_FS_HANDLE] = node->fs_handle, 120 [KEY_DEV_HANDLE] = node->service_id, 121 [KEY_INDEX] = node->index 122 }; 123 124 hash_table_remove(&nodes, key, 3); 120 hash_table_remove_item(&nodes, &node->nh_link); 125 121 free_vfs_node = true; 126 122 … … 160 156 { 161 157 fibril_mutex_lock(&nodes_mutex); 162 unsigned long key[] = { 163 [KEY_FS_HANDLE] = node->fs_handle, 164 [KEY_DEV_HANDLE] = node->service_id, 165 [KEY_INDEX] = node->index 166 }; 167 hash_table_remove(&nodes, key, 3); 158 hash_table_remove_item(&nodes, &node->nh_link); 168 159 fibril_mutex_unlock(&nodes_mutex); 169 160 free(node); … … 184 175 vfs_node_t *vfs_node_get(vfs_lookup_res_t *result) 185 176 { 186 unsigned long key[] = {187 [KEY_FS_HANDLE] = result->triplet.fs_handle,188 [KEY_DEV_HANDLE] = result->triplet.service_id,189 [KEY_INDEX] = result->triplet.index190 };191 link_t *tmp;192 177 vfs_node_t *node; 193 178 194 179 fibril_mutex_lock(&nodes_mutex); 195 tmp = hash_table_find(&nodes, key);180 ht_link_t *tmp = hash_table_find(&nodes, &result->triplet); 196 181 if (!tmp) { 197 182 node = (vfs_node_t *) malloc(sizeof(vfs_node_t)); … … 207 192 node->lnkcnt = result->lnkcnt; 208 193 node->type = result->type; 209 link_initialize(&node->nh_link);210 194 fibril_rwlock_initialize(&node->contents_rwlock); 211 195 hash_table_insert(&nodes, &node->nh_link); 212 196 } else { 213 node = hash_table_get_inst ance(tmp, vfs_node_t, nh_link);197 node = hash_table_get_inst(tmp, vfs_node_t, nh_link); 214 198 if (node->type == VFS_NODE_UNKNOWN && 215 199 result->type != VFS_NODE_UNKNOWN) { … … 242 226 } 243 227 244 size_t nodes_key_hash(unsigned long key[])245 {246 /* Combine into a hash like they do in Effective Java, 2nd edition. */247 size_t hash = 17;248 hash = 37 * hash + key[KEY_FS_HANDLE];249 hash = 37 * hash + key[KEY_DEV_HANDLE];250 hash = 37 * hash + key[KEY_INDEX];251 return hash;252 }253 254 size_t nodes_hash(const link_t *item)255 {256 vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link);257 258 unsigned long key[] = {259 [KEY_FS_HANDLE] = node->fs_handle,260 [KEY_DEV_HANDLE] = node->service_id,261 [KEY_INDEX] = node->index262 };263 264 return nodes_key_hash(key);265 }266 267 268 bool nodes_match(unsigned long key[], size_t keys, const link_t *item)269 {270 vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link);271 return (node->fs_handle == (fs_handle_t) key[KEY_FS_HANDLE]) &&272 (node->service_id == key[KEY_DEV_HANDLE]) &&273 (node->index == key[KEY_INDEX]);274 }275 276 277 228 struct refcnt_data { 278 229 /** Sum of all reference counts for this file system instance. */ … … 282 233 }; 283 234 284 static bool refcnt_visitor( link_t *item, void *arg)285 { 286 vfs_node_t *node = hash_table_get_inst ance(item, vfs_node_t, nh_link);235 static bool refcnt_visitor(ht_link_t *item, void *arg) 236 { 237 vfs_node_t *node = hash_table_get_inst(item, vfs_node_t, nh_link); 287 238 struct refcnt_data *rd = (void *) arg; 288 239 … … 332 283 } 333 284 285 286 static size_t nodes_key_hash(void *key) 287 { 288 vfs_triplet_t *tri = key; 289 size_t hash = hash_combine(tri->fs_handle, tri->index); 290 return hash_combine(hash, tri->service_id); 291 } 292 293 static size_t nodes_hash(const ht_link_t *item) 294 { 295 vfs_node_t *node = hash_table_get_inst(item, vfs_node_t, nh_link); 296 vfs_triplet_t tri = node_triplet(node); 297 return nodes_key_hash(&tri); 298 } 299 300 static bool nodes_key_equal(void *key, const ht_link_t *item) 301 { 302 vfs_triplet_t *tri = key; 303 vfs_node_t *node = hash_table_get_inst(item, vfs_node_t, nh_link); 304 return node->fs_handle == tri->fs_handle 305 && node->service_id == tri->service_id 306 && node->index == tri->index; 307 } 308 309 static inline vfs_triplet_t node_triplet(vfs_node_t *node) 310 { 311 vfs_triplet_t tri = { 312 .fs_handle = node->fs_handle, 313 .service_id = node->service_id, 314 .index = node->index 315 }; 316 317 return tri; 318 } 319 334 320 /** 335 321 * @}
Note:
See TracChangeset
for help on using the changeset viewer.