Changeset 0ca7286 in mainline for uspace/srv/fs/exfat/exfat_idx.c
- Timestamp:
- 2012-07-21T11:19:27Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2732c94
- Parents:
- 1c1da4b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/exfat/exfat_idx.c
r1c1da4b r0ca7286 112 112 static hash_table_t up_hash; 113 113 114 #define UPH_BUCKETS_LOG 12115 #define UPH_BUCKETS (1 << UPH_BUCKETS_LOG)116 117 114 #define UPH_SID_KEY 0 118 115 #define UPH_PFC_KEY 1 119 116 #define UPH_PDI_KEY 2 120 117 121 static hash_index_t pos_hash(unsigned long key[]) 122 { 123 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; 124 exfat_cluster_t pfc = (exfat_cluster_t)key[UPH_PFC_KEY]; 125 unsigned pdi = (unsigned)key[UPH_PDI_KEY]; 126 127 hash_index_t h; 128 129 /* 130 * The least significant half of all bits are the least significant bits 131 * of the parent node's first cluster. 132 * 133 * The least significant half of the most significant half of all bits 134 * are the least significant bits of the node's dentry index within the 135 * parent directory node. 136 * 137 * The most significant half of the most significant half of all bits 138 * are the least significant bits of the device handle. 139 */ 140 h = pfc & ((1 << (UPH_BUCKETS_LOG / 2)) - 1); 141 h |= (pdi & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 142 (UPH_BUCKETS_LOG / 2); 143 h |= (service_id & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) << 144 (3 * (UPH_BUCKETS_LOG / 4)); 145 146 return h; 147 } 148 149 static int pos_compare(unsigned long key[], hash_count_t keys, link_t *item) 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) 150 144 { 151 145 service_id_t service_id = (service_id_t)key[UPH_SID_KEY]; … … 169 163 } 170 164 171 static void pos_remove_callback(link_t *item) 172 { 173 /* nothing to do */ 174 } 175 176 static hash_table_operations_t uph_ops = { 165 static hash_table_ops_t uph_ops = { 177 166 .hash = pos_hash, 178 .compare = pos_compare, 179 .remove_callback = pos_remove_callback, 167 .key_hash = pos_key_hash, 168 .match = pos_match, 169 .equal = 0, 170 .remove_callback = 0, 180 171 }; 181 172 … … 186 177 static hash_table_t ui_hash; 187 178 188 #define UIH_BUCKETS_LOG 12189 #define UIH_BUCKETS (1 << UIH_BUCKETS_LOG)190 191 179 #define UIH_SID_KEY 0 192 180 #define UIH_INDEX_KEY 1 193 181 194 static hash_index_t idx_hash(unsigned long key[])182 static size_t idx_key_hash(unsigned long key[]) 195 183 { 196 184 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; 197 185 fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY]; 198 186 199 hash_index_t h; 200 201 h = service_id & ((1 << (UIH_BUCKETS_LOG / 2)) - 1); 202 h |= (index & ((1 << (UIH_BUCKETS_LOG / 2)) - 1)) << 203 (UIH_BUCKETS_LOG / 2); 204 205 return h; 206 } 207 208 static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item) 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) 209 210 { 210 211 service_id_t service_id = (service_id_t)key[UIH_SID_KEY]; … … 233 234 } 234 235 235 static hash_table_op erations_t uih_ops = {236 static hash_table_ops_t uih_ops = { 236 237 .hash = idx_hash, 237 .compare = idx_compare, 238 .key_hash = idx_key_hash, 239 .match = idx_match, 240 .equal = 0, 238 241 .remove_callback = idx_remove_callback, 239 242 }; … … 400 403 } 401 404 402 unsigned long ikey[] = { 403 [UIH_SID_KEY] = service_id, 404 [UIH_INDEX_KEY] = fidx->index, 405 }; 406 407 hash_table_insert(&ui_hash, ikey, &fidx->uih_link); 405 hash_table_insert(&ui_hash, &fidx->uih_link); 408 406 fibril_mutex_lock(&fidx->lock); 409 407 fibril_mutex_unlock(&used_lock); … … 437 435 } 438 436 439 unsigned long ikey[] = {440 [UIH_SID_KEY] = service_id,441 [UIH_INDEX_KEY] = fidx->index,442 };443 444 437 fidx->pfc = pfc; 445 438 fidx->pdi = pdi; 446 439 447 hash_table_insert(&up_hash, pkey,&fidx->uph_link);448 hash_table_insert(&ui_hash, ikey,&fidx->uih_link);440 hash_table_insert(&up_hash, &fidx->uph_link); 441 hash_table_insert(&ui_hash, &fidx->uih_link); 449 442 } 450 443 fibril_mutex_lock(&fidx->lock); … … 456 449 void exfat_idx_hashin(exfat_idx_t *idx) 457 450 { 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_insert(&up_hash, pkey, &idx->uph_link); 451 fibril_mutex_lock(&used_lock); 452 hash_table_insert(&up_hash, &idx->uph_link); 466 453 fibril_mutex_unlock(&used_lock); 467 454 } … … 532 519 int exfat_idx_init(void) 533 520 { 534 if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops))521 if (!hash_table_create(&up_hash, 0, 3, &uph_ops)) 535 522 return ENOMEM; 536 if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) {523 if (!hash_table_create(&ui_hash, 0, 2, &uih_ops)) { 537 524 hash_table_destroy(&up_hash); 538 525 return ENOMEM;
Note:
See TracChangeset
for help on using the changeset viewer.