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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1d1bb0f was 55b77d9, checked in by Jiri Svoboda <jiri@…>, 14 years ago

Separate list_t typedef from link_t (kernel part).

  • list_t represents lists
  • Use list_first(), list_last(), list_empty() where appropriate
  • Use list_foreach() where possible
  • Replace improper uses of list_prepend() with list_insert_after()
  • Replace improper uses of list_append() with list_insert_before()
  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 * Copyright (c) 2006 Jakub Jermar
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
29/** @addtogroup genericadt
30 * @{
31 */
32
33/**
34 * @file
35 * @brief Implementation of generic chained hash table.
36 *
37 * This file contains implementation of generic chained hash table.
38 */
39
40#include <adt/hash_table.h>
41#include <adt/list.h>
42#include <typedefs.h>
43#include <debug.h>
44#include <mm/slab.h>
45#include <memstr.h>
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 */
54void hash_table_create(hash_table_t *h, size_t m, size_t max_keys, hash_table_operations_t *op)
55{
56 size_t i;
57
58 ASSERT(h);
59 ASSERT(op);
60 ASSERT(op->hash);
61 ASSERT(op->compare);
62 ASSERT(max_keys > 0);
63
64 h->entry = (list_t *) malloc(m * sizeof(list_t), 0);
65 if (!h->entry)
66 panic("Cannot allocate memory for hash table.");
67
68 memsetb(h->entry, m * sizeof(list_t), 0);
69
70 for (i = 0; i < m; i++)
71 list_initialize(&h->entry[i]);
72
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.
81 * @param key Array of all keys necessary to compute hash index.
82 * @param item Item to be inserted into the hash table.
83 */
84void hash_table_insert(hash_table_t *h, sysarg_t key[], link_t *item)
85{
86 size_t chain;
87
88 ASSERT(item);
89 ASSERT(h);
90 ASSERT(h->op);
91 ASSERT(h->op->hash);
92 ASSERT(h->op->compare);
93
94 chain = h->op->hash(key);
95 ASSERT(chain < h->entries);
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 */
107link_t *hash_table_find(hash_table_t *h, sysarg_t key[])
108{
109 size_t chain;
110
111 ASSERT(h);
112 ASSERT(h->op);
113 ASSERT(h->op->hash);
114 ASSERT(h->op->compare);
115
116 chain = h->op->hash(key);
117 ASSERT(chain < h->entries);
118
119 list_foreach(h->entry[chain], cur) {
120 if (h->op->compare(key, h->max_keys, cur)) {
121 /*
122 * The entry is there.
123 */
124 return cur;
125 }
126 }
127
128 return NULL;
129}
130
131/** Remove all matching items from hash table.
132 *
133 * For each removed item, h->remove_callback() is called (if not NULL).
134 *
135 * @param h Hash table.
136 * @param key Array of keys that will be compared against items of the hash table.
137 * @param keys Number of keys in the key array.
138 */
139void hash_table_remove(hash_table_t *h, sysarg_t key[], size_t keys)
140{
141 size_t chain;
142
143 ASSERT(h);
144 ASSERT(h->op);
145 ASSERT(h->op->hash);
146 ASSERT(h->op->compare);
147 ASSERT(keys <= h->max_keys);
148
149 if (keys == h->max_keys) {
150 link_t *cur;
151
152 /*
153 * All keys are known, hash_table_find() can be used to find the entry.
154 */
155
156 cur = hash_table_find(h, key);
157 if (cur) {
158 list_remove(cur);
159 if (h->op->remove_callback)
160 h->op->remove_callback(cur);
161 }
162 return;
163 }
164
165 /*
166 * Fewer keys were passed.
167 * Any partially matching entries are to be removed.
168 */
169 for (chain = 0; chain < h->entries; chain++) {
170 list_foreach(h->entry[chain], cur) {
171 if (h->op->compare(key, keys, cur)) {
172 link_t *hlp;
173
174 hlp = cur;
175 cur = cur->prev;
176
177 list_remove(hlp);
178 if (h->op->remove_callback)
179 h->op->remove_callback(hlp);
180
181 continue;
182 }
183 }
184 }
185}
186
187/** @}
188 */
Note: See TracBrowser for help on using the repository browser.