Changeset 0ca7286 in mainline for uspace/srv/fs/cdfs/cdfs_ops.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/cdfs/cdfs_ops.c
r1c1da4b r0ca7286 63 63 #define NODE_CACHE_SIZE 200 64 64 65 #define NODES_BUCKETS 25666 67 65 #define NODES_KEY_SRVC 0 68 66 #define NODES_KEY_INDEX 1 … … 226 224 static hash_table_t nodes; 227 225 228 static hash_index_t nodes_hash(unsigned long key[]) 229 { 230 return key[NODES_KEY_INDEX] % NODES_BUCKETS; 231 } 232 233 static int nodes_compare(unsigned long key[], hash_count_t keys, link_t *item) 234 { 235 cdfs_node_t *node = 236 hash_table_get_instance(item, cdfs_node_t, nh_link); 237 238 switch (keys) { 239 case 1: 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) { 240 247 return (node->service_id == key[NODES_KEY_SRVC]); 241 case 2: 248 } else { 249 assert(keys == 2); 242 250 return ((node->service_id == key[NODES_KEY_SRVC]) && 243 251 (node->index == key[NODES_KEY_INDEX])); 244 default: 245 assert((keys == 1) || (keys == 2)); 246 } 247 248 return 0; 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; 249 262 } 250 263 251 264 static void nodes_remove_callback(link_t *item) 252 265 { 253 cdfs_node_t *node = 254 hash_table_get_instance(item, cdfs_node_t, nh_link); 266 cdfs_node_t *node = hash_table_get_instance(item, cdfs_node_t, nh_link); 255 267 256 268 assert(node->type == CDFS_DIRECTORY); … … 268 280 269 281 /** Nodes hash table operations */ 270 static hash_table_op erations_t nodes_ops = {282 static hash_table_ops_t nodes_ops = { 271 283 .hash = nodes_hash, 272 .compare = nodes_compare, 284 .key_hash = nodes_key_hash, 285 .match = nodes_match, 286 .equal = nodes_equal, 273 287 .remove_callback = nodes_remove_callback 274 288 }; … … 353 367 354 368 /* Insert the new node into the nodes hash table. */ 355 unsigned long key[] = { 356 [NODES_KEY_SRVC] = node->service_id, 357 [NODES_KEY_INDEX] = node->index 358 }; 359 360 hash_table_insert(&nodes, key, &node->nh_link); 369 hash_table_insert(&nodes, &node->nh_link); 361 370 362 371 *rfn = FS_NODE(node); … … 912 921 } 913 922 923 static bool cache_remove_closed(link_t *item, void *arg) 924 { 925 size_t *premove_cnt = (size_t*)arg; 926 927 /* Some nodes were requested to be removed from the cache. */ 928 if (0 < *premove_cnt) { 929 cdfs_node_t *node = hash_table_get_instance(item, cdfs_node_t, nh_link); 930 931 if (!node->opened) { 932 hash_table_remove_item(&nodes, item); 933 934 --nodes_cached; 935 --*premove_cnt; 936 } 937 } 938 939 /* Only continue if more nodes were requested to be removed. */ 940 return 0 < *premove_cnt; 941 } 942 914 943 static void cleanup_cache(service_id_t service_id) 915 944 { 916 945 if (nodes_cached > NODE_CACHE_SIZE) { 917 size_t remove = nodes_cached - NODE_CACHE_SIZE; 918 919 // FIXME: this accesses the internals of the hash table 920 // and should be rewritten in a clean way 921 922 for (hash_index_t chain = 0; chain < nodes.entries; chain++) { 923 for (link_t *link = nodes.entry[chain].head.next; 924 link != &nodes.entry[chain].head; 925 link = link->next) { 926 if (remove == 0) 927 return; 928 929 cdfs_node_t *node = 930 hash_table_get_instance(link, cdfs_node_t, nh_link); 931 if (node->opened == 0) { 932 link_t *tmp = link; 933 link = link->prev; 934 935 list_remove(tmp); 936 nodes.op->remove_callback(tmp); 937 nodes_cached--; 938 remove--; 939 940 continue; 941 } 942 } 943 } 946 size_t remove_cnt = nodes_cached - NODE_CACHE_SIZE; 947 948 if (0 < remove_cnt) 949 hash_table_apply(&nodes, cache_remove_closed, &remove_cnt); 944 950 } 945 951 } … … 1007 1013 bool cdfs_init(void) 1008 1014 { 1009 if (!hash_table_create(&nodes, NODES_BUCKETS, 2, &nodes_ops))1015 if (!hash_table_create(&nodes, 0, 2, &nodes_ops)) 1010 1016 return false; 1011 1017
Note:
See TracChangeset
for help on using the changeset viewer.