source: mainline/kernel/generic/src/adt/hash_table.c@ e9d15d9

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e9d15d9 was 1c85bae, checked in by Jakub Jermar <jakub@…>, 8 years ago

Add hash_table_remove_item()

  • Property mode set to 100644
File size: 5.1 KB
RevLine 
[c585827]1/*
[df4ed85]2 * Copyright (c) 2006 Jakub Jermar
[c585827]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[cc73a8a1]29/** @addtogroup genericadt
[b45c443]30 * @{
31 */
32
[9179d0a]33/**
[7257021e]34 * @file
[7b0297b]35 * @brief Implementation of generic chained hash table.
[9179d0a]36 *
37 * This file contains implementation of generic chained hash table.
[c585827]38 */
39
40#include <adt/hash_table.h>
41#include <adt/list.h>
[63e27ef]42#include <assert.h>
[d99c1d2]43#include <typedefs.h>
[085d973]44#include <mm/slab.h>
[44a7ee5]45#include <mem.h>
[c585827]46
47/** Create chained hash table.
48 *
49 * @param h Hash table structure. Will be initialized by this call.
50 * @param m Number of slots in the hash table.
51 * @param max_keys Maximal number of keys needed to identify an item.
52 * @param op Hash table operations structure.
53 */
[98000fb]54void hash_table_create(hash_table_t *h, size_t m, size_t max_keys, hash_table_operations_t *op)
[c585827]55{
[98000fb]56 size_t i;
[9ad03fe]57
[63e27ef]58 assert(h);
59 assert(op);
60 assert(op->hash);
61 assert(op->compare);
62 assert(max_keys > 0);
[c585827]63
[55b77d9]64 h->entry = (list_t *) malloc(m * sizeof(list_t), 0);
[7b0297b]65 if (!h->entry)
[f651e80]66 panic("Cannot allocate memory for hash table.");
[7b0297b]67
[55b77d9]68 memsetb(h->entry, m * sizeof(list_t), 0);
[c585827]69
[9ad03fe]70 for (i = 0; i < m; i++)
71 list_initialize(&h->entry[i]);
72
[c585827]73 h->entries = m;
74 h->max_keys = max_keys;
75 h->op = op;
76}
77
78/** Insert item into hash table.
79 *
80 * @param h Hash table.
[abbc16e]81 * @param key Array of all keys necessary to compute hash index.
[c585827]82 * @param item Item to be inserted into the hash table.
83 */
[96b02eb9]84void hash_table_insert(hash_table_t *h, sysarg_t key[], link_t *item)
[c585827]85{
[98000fb]86 size_t chain;
[7b0297b]87
[63e27ef]88 assert(item);
89 assert(h);
90 assert(h->op);
91 assert(h->op->hash);
92 assert(h->op->compare);
[7b0297b]93
[c585827]94 chain = h->op->hash(key);
[63e27ef]95 assert(chain < h->entries);
[c585827]96
97 list_append(item, &h->entry[chain]);
98}
99
100/** Search hash table for an item matching keys.
101 *
102 * @param h Hash table.
103 * @param key Array of all keys needed to compute hash index.
104 *
105 * @return Matching item on success, NULL if there is no such item.
106 */
[96b02eb9]107link_t *hash_table_find(hash_table_t *h, sysarg_t key[])
[c585827]108{
[98000fb]109 size_t chain;
[7b0297b]110
[63e27ef]111 assert(h);
112 assert(h->op);
113 assert(h->op->hash);
114 assert(h->op->compare);
[7b0297b]115
[c585827]116 chain = h->op->hash(key);
[63e27ef]117 assert(chain < h->entries);
[c585827]118
[feeac0d]119 link_t *cur = list_first(&h->entry[chain]);
120 while (cur != NULL) {
[c585827]121 if (h->op->compare(key, h->max_keys, cur)) {
122 /*
123 * The entry is there.
124 */
125 return cur;
126 }
[feeac0d]127 cur = list_next(cur, &h->entry[chain]);
[c585827]128 }
129
130 return NULL;
131}
132
133/** Remove all matching items from hash table.
134 *
[b014e9f]135 * For each removed item, h->remove_callback() is called (if not NULL).
[c585827]136 *
137 * @param h Hash table.
138 * @param key Array of keys that will be compared against items of the hash table.
[9179d0a]139 * @param keys Number of keys in the key array.
[c585827]140 */
[96b02eb9]141void hash_table_remove(hash_table_t *h, sysarg_t key[], size_t keys)
[c585827]142{
[98000fb]143 size_t chain;
[7b0297b]144
[63e27ef]145 assert(h);
146 assert(h->op);
147 assert(h->op->hash);
148 assert(h->op->compare);
149 assert(keys <= h->max_keys);
[c585827]150
[b72efe8]151
[c585827]152 if (keys == h->max_keys) {
[55b77d9]153 link_t *cur;
[b72efe8]154
[c585827]155 /*
156 * All keys are known, hash_table_find() can be used to find the entry.
157 */
158
159 cur = hash_table_find(h, key);
160 if (cur) {
161 list_remove(cur);
[b014e9f]162 if (h->op->remove_callback)
163 h->op->remove_callback(cur);
[c585827]164 }
165 return;
166 }
167
168 /*
169 * Fewer keys were passed.
170 * Any partially matching entries are to be removed.
171 */
172 for (chain = 0; chain < h->entries; chain++) {
[b72efe8]173 link_t *cur;
174 for (cur = h->entry[chain].head.next; cur != &h->entry[chain].head;
175 cur = cur->next) {
[c585827]176 if (h->op->compare(key, keys, cur)) {
177 link_t *hlp;
178
179 hlp = cur;
180 cur = cur->prev;
181
182 list_remove(hlp);
[b014e9f]183 if (h->op->remove_callback)
184 h->op->remove_callback(hlp);
[c585827]185
186 continue;
187 }
188 }
189 }
190}
[b45c443]191
[1c85bae]192/** Remove an existing item from hash table.
193 *
194 * @param h Hash table.
195 * @param item Item to remove from the hash table.
196 */
197void hash_table_remove_item(hash_table_t *h, link_t *item)
198{
199 assert(h);
200 assert(h->op);
201
202 list_remove(item);
203 if (h->op->remove_callback)
204 h->op->remove_callback(item);
205}
206
[cc73a8a1]207/** @}
[b45c443]208 */
Note: See TracBrowser for help on using the repository browser.