Changeset bc216a0 in mainline for uspace/srv/fs/exfat/exfat_idx.c
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.