Changeset 0db0df2 in mainline
- Timestamp:
- 2025-04-07T17:53:53Z (14 hours ago)
- Branches:
- master
- Children:
- 0c6fc7a, 708bfeb, 93de384, e92052d
- Parents:
- 8f8818ac
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-07 16:41:57)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-07 17:53:53)
- Files:
-
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
common/adt/hash_table.c
r8f8818ac r0db0df2 247 247 assert(h && h->bucket); 248 248 249 size_t idx = h->op->key_hash(key) % h->bucket_cnt; 249 size_t hash = h->op->key_hash(key); 250 size_t idx = hash % h->bucket_cnt; 250 251 251 252 list_foreach(h->bucket[idx], link, ht_link_t, cur_link) { 252 /* 253 * Is this is the item we are looking for? We could have first 254 * checked if the hashes match but op->key_equal() may very well be 255 * just as fast as op->hash(). 256 */ 257 if (h->op->key_equal(key, cur_link)) { 253 if (h->op->key_equal(key, hash, cur_link)) 258 254 return cur_link; 259 }260 255 } 261 256 … … 265 260 /** Find the next item equal to item. */ 266 261 ht_link_t * 267 hash_table_find_next(const hash_table_t *h, ht_link_t * first, ht_link_t *item)262 hash_table_find_next(const hash_table_t *h, ht_link_t *item) 268 263 { 269 264 assert(item); … … 271 266 272 267 size_t idx = h->op->hash(item) % h->bucket_cnt; 273 274 /* Traverse the circular list until we reach the starting item again. */ 275 for (link_t *cur = item->link.next; cur != &first->link; 276 cur = cur->next) { 277 assert(cur); 278 279 if (cur == &h->bucket[idx].head) 280 continue; 281 268 list_t *list = &h->bucket[idx]; 269 link_t *cur = list_next(&item->link, list); 270 271 /* Traverse the list until we reach its end. */ 272 for (; cur != NULL; cur = list_next(cur, list)) { 282 273 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 283 /* 284 * Is this is the item we are looking for? We could have first 285 * checked if the hashes match but op->equal() may very well be 286 * just as fast as op->hash(). 287 */ 288 if (h->op->equal(cur_link, item)) { 274 275 if (h->op->equal(cur_link, item)) 289 276 return cur_link; 290 }291 277 } 292 278 … … 309 295 assert(!h->apply_ongoing); 310 296 311 size_t idx = h->op->key_hash(key) % h->bucket_cnt; 297 size_t hash = h->op->key_hash(key); 298 size_t idx = hash % h->bucket_cnt; 312 299 313 300 size_t removed = 0; … … 316 303 ht_link_t *cur_link = member_to_inst(cur, ht_link_t, link); 317 304 318 if (h->op->key_equal(key, cur_link)) {305 if (h->op->key_equal(key, hash, cur_link)) { 319 306 ++removed; 320 307 list_remove(cur); -
common/include/adt/hash.h
r8f8818ac r0db0df2 108 108 } 109 109 110 /** Hash a NUL-terminated string. 111 * The algorithm may change in the future, so never use it for hashes 112 * that will be stored to a file or sent over a network. 113 */ 114 static inline size_t hash_string(const char *str) 115 { 116 /* djb2 hash + extra mixing at the end */ 117 118 char c; 119 size_t hash = 5381; 120 121 while ((c = *(str++))) 122 hash = (hash << 5) + hash + c; 123 124 return hash_mix(hash); 125 } 126 127 /** Hash an arbitrarily sized sequence of bytes. 128 * The algorithm may change in the future, so never use it for hashes 129 * that will be stored to a file or sent over a network. 130 */ 131 static inline size_t hash_bytes(const void *b, size_t len) 132 { 133 /* djb2 hash + extra mixing at the end */ 134 135 // TODO: work in bigger chunks for faster hashing 136 137 const char *str = b; 138 139 size_t hash = 5381; 140 141 for (size_t i = 0; i < len; i++) 142 hash = (hash << 5) + hash + str[i]; 143 144 return hash_mix(hash); 145 } 146 110 147 #endif -
common/include/adt/hash_table.h
r8f8818ac r0db0df2 60 60 61 61 /** Returns true if the key is equal to the item's lookup key. */ 62 bool (*key_equal)(const void *key, const ht_link_t *item);62 bool (*key_equal)(const void *key, size_t hash, const ht_link_t *item); 63 63 64 64 /** Hash table item removal callback. … … 85 85 member_to_inst((item), type, member) 86 86 87 #define hash_table_foreach(ht, key, member, itype, iterator) \ 88 for (itype *iterator = NULL; \ 89 iterator == NULL; iterator = (itype *) INTPTR_MAX) \ 90 for (ht_link_t *__link = hash_table_find((ht), (key)); \ 91 __link != NULL && ((iterator = member_to_inst(__link, itype, member))); \ 92 __link = hash_table_find_next((ht), __link)) 93 87 94 extern bool hash_table_create(hash_table_t *, size_t, size_t, 88 95 const hash_table_ops_t *); … … 96 103 extern bool hash_table_insert_unique(hash_table_t *, ht_link_t *); 97 104 extern ht_link_t *hash_table_find(const hash_table_t *, const void *); 98 extern ht_link_t *hash_table_find_next(const hash_table_t *, ht_link_t *, 99 ht_link_t *); 105 extern ht_link_t *hash_table_find_next(const hash_table_t *, ht_link_t *); 100 106 extern size_t hash_table_remove(hash_table_t *, const void *); 101 107 extern void hash_table_remove_item(hash_table_t *, ht_link_t *); -
kernel/genarch/src/mm/page_ht.c
r8f8818ac r0db0df2 55 55 static size_t ht_hash(const ht_link_t *); 56 56 static size_t ht_key_hash(const void *); 57 static bool ht_key_equal(const void *, const ht_link_t *);57 static bool ht_key_equal(const void *, size_t, const ht_link_t *); 58 58 static void ht_remove_callback(ht_link_t *); 59 59 … … 119 119 120 120 /** Return true if the key is equal to the item's lookup key. */ 121 bool ht_key_equal(const void *arg, const ht_link_t *item)121 bool ht_key_equal(const void *arg, size_t hash, const ht_link_t *item) 122 122 { 123 123 const uintptr_t *key = arg; -
kernel/generic/src/cap/cap.c
r8f8818ac r0db0df2 118 118 } 119 119 120 static bool caps_key_equal(const void *key, const ht_link_t *item)120 static bool caps_key_equal(const void *key, size_t hash, const ht_link_t *item) 121 121 { 122 122 const cap_handle_t *handle = key; -
kernel/generic/src/ddi/irq.c
r8f8818ac r0db0df2 75 75 static size_t irq_ht_key_hash(const void *); 76 76 static bool irq_ht_equal(const ht_link_t *, const ht_link_t *); 77 static bool irq_ht_key_equal(const void *, const ht_link_t *);77 static bool irq_ht_key_equal(const void *, size_t, const ht_link_t *); 78 78 79 79 static const hash_table_ops_t irq_ht_ops = { … … 141 141 { 142 142 irq_spinlock_lock(l, false); 143 ht_link_t *first = hash_table_find(h, &inr); 144 for (ht_link_t *lnk = first; lnk; 145 lnk = hash_table_find_next(h, first, lnk)) { 146 irq_t *irq = hash_table_get_inst(lnk, irq_t, link); 143 144 hash_table_foreach(h, &inr, link, irq_t, irq) { 147 145 irq_spinlock_lock(&irq->lock, false); 148 146 if (irq->claim(irq) == IRQ_ACCEPT) { … … 153 151 irq_spinlock_unlock(&irq->lock, false); 154 152 } 153 155 154 irq_spinlock_unlock(l, false); 156 155 … … 223 222 224 223 /** Return true if the key is equal to the item's lookup key. */ 225 bool irq_ht_key_equal(const void *key, const ht_link_t *item)224 bool irq_ht_key_equal(const void *key, size_t hash, const ht_link_t *item) 226 225 { 227 226 const inr_t *inr = key; -
kernel/generic/src/lib/ra.c
r8f8818ac r0db0df2 74 74 75 75 /** Return true if the key is equal to the item's lookup key */ 76 static bool used_key_equal(const void *key, const ht_link_t *item)76 static bool used_key_equal(const void *key, size_t, const ht_link_t *item) 77 77 { 78 78 const uintptr_t *base = key; -
uspace/app/hbench/env.c
r8f8818ac r0db0df2 34 34 */ 35 35 36 #include <adt/hash.h> 36 37 #include <stdlib.h> 37 38 #include <stdio.h> … … 42 43 ht_link_t link; 43 44 45 size_t hash; 44 46 char *key; 45 47 char *value; … … 49 51 { 50 52 param_t *param = hash_table_get_inst(item, param_t, link); 51 return str_size(param->key);53 return param->hash; 52 54 } 53 55 54 56 static size_t param_key_hash(const void *key) 55 57 { 56 const char *key_str = key; 57 return str_size(key_str); 58 return hash_string(key); 58 59 } 59 60 60 static bool param_key_equal(const void *key, const ht_link_t *item)61 static bool param_key_equal(const void *key, size_t hash, const ht_link_t *item) 61 62 { 62 63 param_t *param = hash_table_get_inst(item, param_t, link); 64 65 if (param->hash != hash) 66 return false; 67 63 68 const char *key_str = key; 64 65 69 return str_cmp(param->key, key_str) == 0; 66 70 } … … 71 75 param_t *b = hash_table_get_inst(link_b, param_t, link); 72 76 73 return str_cmp(a->key, b->key) == 0;77 return a->hash == b->hash && str_cmp(a->key, b->key) == 0; 74 78 } 75 79 … … 116 120 param->key = str_dup(key); 117 121 param->value = str_dup(value); 122 param->hash = hash_string(key); 118 123 119 124 if ((param->key == NULL) || (param->value == NULL)) { … … 132 137 const char *bench_env_param_get(bench_env_t *env, const char *key, const char *default_value) 133 138 { 134 ht_link_t *item = hash_table_find(&env->parameters, (char *)key);139 ht_link_t *item = hash_table_find(&env->parameters, key); 135 140 136 141 if (item == NULL) { -
uspace/app/trace/ipcp.c
r8f8818ac r0db0df2 84 84 } 85 85 86 static bool pending_call_key_equal(const void *key, const ht_link_t *item)86 static bool pending_call_key_equal(const void *key, size_t hash, const ht_link_t *item) 87 87 { 88 88 const cap_call_handle_t *chandle = key; -
uspace/app/trace/proto.c
r8f8818ac r0db0df2 69 69 } 70 70 71 static bool srv_proto_key_equal(const void *key, const ht_link_t *item)71 static bool srv_proto_key_equal(const void *key, size_t hash, const ht_link_t *item) 72 72 { 73 73 const int *n = key; … … 96 96 } 97 97 98 static bool method_oper_key_equal(const void *key, const ht_link_t *item)98 static bool method_oper_key_equal(const void *key, size_t hash, const ht_link_t *item) 99 99 { 100 100 const int *n = key; -
uspace/lib/block/block.c
r8f8818ac r0db0df2 254 254 } 255 255 256 static bool cache_key_equal(const void *key, const ht_link_t *item)256 static bool cache_key_equal(const void *key, size_t hash, const ht_link_t *item) 257 257 { 258 258 const aoff64_t *lba = key; -
uspace/lib/c/generic/async/ports.c
r8f8818ac r0db0df2 50 50 #include <as.h> 51 51 #include <abi/mm/as.h> 52 #include "../private/libc.h"53 52 #include "../private/fibril.h" 54 53 … … 115 114 } 116 115 117 static bool interface_key_equal(const void *key, const ht_link_t *item)116 static bool interface_key_equal(const void *key, size_t hash, const ht_link_t *item) 118 117 { 119 118 const iface_t *iface = key; … … 143 142 } 144 143 145 static bool port_key_equal(const void *key, const ht_link_t *item)144 static bool port_key_equal(const void *key, size_t hash, const ht_link_t *item) 146 145 { 147 146 const port_id_t *port_id = key; -
uspace/lib/c/generic/async/server.c
r8f8818ac r0db0df2 242 242 } 243 243 244 static bool client_key_equal(const void *key, const ht_link_t *item)244 static bool client_key_equal(const void *key, size_t, const ht_link_t *item) 245 245 { 246 246 const task_id_t *in_task_id = key; … … 502 502 } 503 503 504 static bool notification_key_equal(const void *key, const ht_link_t *item)504 static bool notification_key_equal(const void *key, size_t hash, const ht_link_t *item) 505 505 { 506 506 const sysarg_t *id = key; -
uspace/lib/ext4/src/ops.c
r8f8818ac r0db0df2 113 113 } 114 114 115 static bool open_nodes_key_equal(const void *key_arg, const ht_link_t *item)115 static bool open_nodes_key_equal(const void *key_arg, size_t hash, const ht_link_t *item) 116 116 { 117 117 const node_key_t *key = key_arg; -
uspace/lib/nic/src/nic_addr_db.c
r8f8818ac r0db0df2 52 52 typedef struct nic_addr_entry { 53 53 ht_link_t link; 54 size_t hash; 54 55 uint8_t len; 55 uint8_t addr[ 1];56 uint8_t addr[]; 56 57 } nic_addr_entry_t; 57 58 … … 60 61 */ 61 62 typedef struct { 63 size_t hash; 62 64 size_t len; 63 65 const uint8_t *addr; 64 66 } addr_key_t; 65 67 66 static bool nic_addr_key_equal(const void *key_arg, const ht_link_t *item)68 static bool nic_addr_key_equal(const void *key_arg, size_t hash, const ht_link_t *item) 67 69 { 68 70 const addr_key_t *key = key_arg; 69 71 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 70 71 return memcmp(entry->addr, key->addr, entry->len) == 0; 72 return entry->hash == hash && memcmp(entry->addr, key->addr, entry->len) == 0; 72 73 } 73 74 … … 86 87 { 87 88 const addr_key_t *key = k; 88 return addr_hash(key->len, key->addr);89 return key->hash ? key->hash : addr_hash(key->len, key->addr); 89 90 } 90 91 … … 92 93 { 93 94 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 94 return addr_hash(entry->len, entry->addr);95 return entry->hash; 95 96 } 96 97 … … 98 99 { 99 100 nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link); 100 101 101 free(entry); 102 102 } … … 173 173 addr_key_t key = { 174 174 .len = db->addr_len, 175 .addr = addr 175 .addr = addr, 176 .hash = addr_hash(db->addr_len, addr), 176 177 }; 177 178 … … 179 180 return EEXIST; 180 181 181 nic_addr_entry_t *entry = malloc( sizeof(nic_addr_entry_t) + db->addr_len - 1);182 nic_addr_entry_t *entry = malloc(offsetof(nic_addr_entry_t, addr) + db->addr_len); 182 183 if (entry == NULL) 183 184 return ENOMEM; … … 185 186 entry->len = (uint8_t) db->addr_len; 186 187 memcpy(entry->addr, addr, db->addr_len); 188 entry->hash = key.hash; 187 189 188 190 hash_table_insert(&db->set, &entry->link); -
uspace/lib/nic/src/nic_wol_virtues.c
r8f8818ac r0db0df2 57 57 } 58 58 59 static bool nic_wv_key_equal(const void *key, const ht_link_t *item)59 static bool nic_wv_key_equal(const void *key, size_t hash, const ht_link_t *item) 60 60 { 61 61 const nic_wv_id_t *k = key; -
uspace/srv/devman/devtree.c
r8f8818ac r0db0df2 32 32 */ 33 33 34 #include <errno.h>35 34 #include <io/log.h> 36 35 … … 61 60 } 62 61 63 static bool devman_devices_key_equal(const void *key, const ht_link_t *item)62 static bool devman_devices_key_equal(const void *key, size_t hash, const ht_link_t *item) 64 63 { 65 64 const devman_handle_t *handle = key; … … 68 67 } 69 68 70 static bool devman_functions_key_equal(const void *key, const ht_link_t *item)69 static bool devman_functions_key_equal(const void *key, size_t hash, const ht_link_t *item) 71 70 { 72 71 const devman_handle_t *handle = key; … … 87 86 } 88 87 89 static bool loc_functions_key_equal(const void *key, const ht_link_t *item)88 static bool loc_functions_key_equal(const void *key, size_t hash, const ht_link_t *item) 90 89 { 91 90 const service_id_t *service_id = key; -
uspace/srv/fs/cdfs/cdfs_ops.c
r8f8818ac r0db0df2 298 298 } 299 299 300 static bool nodes_key_equal(const void *k, const ht_link_t *item)300 static bool nodes_key_equal(const void *k, size_t hash, const ht_link_t *item) 301 301 { 302 302 cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link); -
uspace/srv/fs/exfat/exfat_idx.c
r8f8818ac r0db0df2 37 37 38 38 #include "exfat.h" 39 #include "../../vfs/vfs.h"40 39 #include <errno.h> 41 40 #include <str.h> … … 139 138 } 140 139 141 static bool pos_key_equal(const void *key, const ht_link_t *item)140 static bool pos_key_equal(const void *key, size_t hash, const ht_link_t *item) 142 141 { 143 142 const pos_key_t *pos = key; … … 180 179 } 181 180 182 static bool idx_key_equal(const void *key_arg, const ht_link_t *item) 181 static bool idx_key_equal(const void *key_arg, size_t hash, 182 const ht_link_t *item) 183 183 { 184 184 exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link); -
uspace/srv/fs/fat/fat_idx.c
r8f8818ac r0db0df2 37 37 38 38 #include "fat.h" 39 #include "../../vfs/vfs.h"40 39 #include <errno.h> 41 40 #include <str.h> … … 139 138 } 140 139 141 static bool pos_key_equal(const void *key, const ht_link_t *item)140 static bool pos_key_equal(const void *key, size_t hash, const ht_link_t *item) 142 141 { 143 142 const pos_key_t *pos = key; … … 180 179 } 181 180 182 static bool idx_key_equal(const void *key_arg, const ht_link_t *item) 181 static bool idx_key_equal(const void *key_arg, size_t hash, 182 const ht_link_t *item) 183 183 { 184 184 fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link); -
uspace/srv/fs/locfs/locfs_ops.c
r8f8818ac r0db0df2 83 83 } 84 84 85 static bool services_key_equal(const void *key, const ht_link_t *item) 85 static bool services_key_equal(const void *key, size_t hash, 86 const ht_link_t *item) 86 87 { 87 88 const service_id_t *k = key; -
uspace/srv/fs/mfs/mfs_ops.c
r8f8818ac r0db0df2 115 115 116 116 static bool 117 open_nodes_key_equal(const void *key, const ht_link_t *item)117 open_nodes_key_equal(const void *key, size_t hash, const ht_link_t *item) 118 118 { 119 119 const node_key_t *node_key = key; -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r8f8818ac r0db0df2 38 38 39 39 #include "tmpfs.h" 40 #include "../../vfs/vfs.h"41 40 #include <macros.h> 42 41 #include <stdint.h> … … 159 158 } 160 159 161 static bool nodes_key_equal(const void *key_arg, const ht_link_t *item) 160 static bool nodes_key_equal(const void *key_arg, size_t hash, 161 const ht_link_t *item) 162 162 { 163 163 tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link); -
uspace/srv/fs/udf/udf_idx.c
r8f8818ac r0db0df2 35 35 */ 36 36 37 #include "../../vfs/vfs.h"38 37 #include <errno.h> 39 38 #include <str.h> … … 69 68 } 70 69 71 static bool udf_idx_key_equal(const void *k, const ht_link_t *item)70 static bool udf_idx_key_equal(const void *k, size_t hash, const ht_link_t *item) 72 71 { 73 72 const udf_ht_key_t *key = k; -
uspace/srv/hid/input/gsp.c
r8f8818ac r0db0df2 76 76 } 77 77 78 static bool trans_key_equal(const void *key, const ht_link_t *item)78 static bool trans_key_equal(const void *key, size_t hash, const ht_link_t *item) 79 79 { 80 80 const trans_key_t *trans_key = key; -
uspace/srv/ns/service.c
r8f8818ac r0db0df2 79 79 } 80 80 81 static bool service_key_equal(const void *key, const ht_link_t *item) 81 static bool service_key_equal(const void *key, size_t hash, 82 const ht_link_t *item) 82 83 { 83 84 const service_t *srv = key; … … 102 103 } 103 104 104 static bool iface_key_equal(const void *key, const ht_link_t *item)105 static bool iface_key_equal(const void *key, size_t hash, const ht_link_t *item) 105 106 { 106 107 const iface_t *kiface = key; -
uspace/srv/ns/task.c
r8f8818ac r0db0df2 66 66 } 67 67 68 static bool task_key_equal(const void *key, const ht_link_t *item)68 static bool task_key_equal(const void *key, size_t hash, const ht_link_t *item) 69 69 { 70 70 const task_id_t *tid = key; … … 111 111 } 112 112 113 static bool p2i_key_equal(const void *key, const ht_link_t *item)113 static bool p2i_key_equal(const void *key, size_t hash, const ht_link_t *item) 114 114 { 115 115 const sysarg_t *label = key; -
uspace/srv/vfs/vfs_node.c
r8f8818ac r0db0df2 62 62 static size_t nodes_key_hash(const void *); 63 63 static size_t nodes_hash(const ht_link_t *); 64 static bool nodes_key_equal(const void *, const ht_link_t *);64 static bool nodes_key_equal(const void *, size_t, const ht_link_t *); 65 65 static vfs_triplet_t node_triplet(vfs_node_t *node); 66 66 … … 294 294 } 295 295 296 static bool nodes_key_equal(const void *key, const ht_link_t *item)296 static bool nodes_key_equal(const void *key, size_t hash, const ht_link_t *item) 297 297 { 298 298 const vfs_triplet_t *tri = key;
Note:
See TracChangeset
for help on using the changeset viewer.