| 161 | } |
| 162 | |
| 163 | struct hash_elem * hash_remove(struct hash *hash, struct hash_elem *e) |
| 164 | { |
| 165 | int bucket = hash->hash_func(hash, e); |
| 166 | struct hash_elem *hash_elem; |
| 167 | |
| 168 | IFDEF_LOCK( spin_lock(hash->locks + bucket) ); |
| 169 | |
| 170 | #ifdef _HASH_TREE |
| 171 | struct avl_node *node; |
| 172 | node = avl_search(hash->buckets + bucket, &e->avl, _hash_cmp_wrap); |
| 173 | if (node) { |
| 174 | avl_remove(hash->buckets + bucket, node); |
| 175 | IFDEF_LOCK( spin_unlock(hash->locks + bucket) ); |
| 176 | hash_elem = _get_entry(node, struct hash_elem, avl); |
| 177 | return hash_elem; |
| 178 | } |
| 179 | |
| 180 | #else |
| 181 | struct list_elem *le; |
| 182 | le = list_begin(hash->buckets + bucket); |
| 183 | while(le) { |
| 184 | hash_elem = _get_entry(le, struct hash_elem, list_elem); |
| 185 | if (!hash->cmp(e, hash_elem)) { |
| 186 | list_remove(hash->buckets + bucket, le); |
| 187 | |
| 188 | IFDEF_LOCK( spin_unlock(hash->locks + bucket) ); |
| 189 | |
| 190 | return hash_elem; |
| 191 | } |
| 192 | le = list_next(le); |
| 193 | } |
| 194 | #endif |
| 195 | |
| 196 | IFDEF_LOCK( spin_unlock(hash->locks + bucket) ); |
| 197 | |
| 198 | return NULL; |
| 199 | } |
| 200 | |
| 201 | void hash_free(struct hash *hash) |
| 202 | { |