4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
32 static int hash_string(const char *, long);
35 make_hash(size_t size
)
39 ptr
= malloc(sizeof (*ptr
));
41 ptr
->table
= malloc((size_t)(sizeof (hash_entry
*) * size
));
42 (void) memset((char *)ptr
->table
, 0, sizeof (hash_entry
*) * size
);
44 ptr
->hash_type
= String_Key
;
49 make_ihash(size_t size
)
53 ptr
= malloc(sizeof (*ptr
));
55 ptr
->table
= malloc(sizeof (hash_entry
*) * size
);
56 (void) memset((char *)ptr
->table
, 0, sizeof (hash_entry
*) * size
);
58 ptr
->hash_type
= Integer_Key
;
63 get_hash(hash
*tbl
, char *key
)
66 hash_entry
*tmp
, *new;
68 if (tbl
->hash_type
== String_Key
) {
69 tmp
= tbl
->table
[bucket
= hash_string(key
, tbl
->size
)];
71 tmp
= tbl
->table
[bucket
= labs((long)key
) % tbl
->size
];
74 if (tbl
->hash_type
== String_Key
) {
76 if (strcmp(tmp
->key
, key
) == 0) {
79 tmp
= tmp
->next_entry
;
83 if (tmp
->key
== key
) {
86 tmp
= tmp
->next_entry
;
92 * insert new entry into bucket...
94 new = malloc(sizeof (*new));
95 new->key
= ((tbl
->hash_type
== String_Key
)?strdup(key
):key
);
98 * hook into chain from tbl...
100 new->right_entry
= NULL
;
101 new->left_entry
= tbl
->start
;
105 * hook into bucket chain
107 new->next_entry
= tbl
->table
[bucket
];
108 tbl
->table
[bucket
] = new;
109 new->data
= NULL
; /* so we know that it is new */
114 find_hash(hash
*tbl
, const char *key
)
118 if (tbl
->hash_type
== String_Key
) {
119 tmp
= tbl
->table
[hash_string(key
, tbl
->size
)];
120 for (; tmp
!= NULL
; tmp
= tmp
->next_entry
) {
121 if (strcmp(tmp
->key
, key
) == 0) {
126 tmp
= tbl
->table
[labs((long)key
) % tbl
->size
];
127 for (; tmp
!= NULL
; tmp
= tmp
->next_entry
) {
128 if (tmp
->key
== key
) {
137 del_hash(hash
*tbl
, const char *key
)
140 hash_entry
* tmp
, * prev
= NULL
;
142 if (tbl
->hash_type
== String_Key
) {
143 bucket
= hash_string(key
, tbl
->size
);
145 bucket
= labs((long)key
) % tbl
->size
;
148 if ((tmp
= tbl
->table
[bucket
]) == NULL
) {
151 if (tbl
->hash_type
== String_Key
) {
152 while (tmp
!= NULL
) {
153 if (strcmp(tmp
->key
, key
) == 0) {
154 break; /* found item to delete ! */
157 tmp
= tmp
->next_entry
;
160 while (tmp
!= NULL
) {
161 if (tmp
->key
== key
) {
165 tmp
= tmp
->next_entry
;
169 return (NULL
); /* not found */
174 * tmp now points to entry marked for deletion, prev to
175 * item preceding in bucket chain or NULL if tmp is first.
176 * remove from bucket chain first....
178 if (tbl
->hash_type
== String_Key
) {
182 prev
->next_entry
= tmp
->next_entry
;
184 tbl
->table
[bucket
] = tmp
->next_entry
;
188 * now remove from tbl chain....
190 if (tmp
->right_entry
!= NULL
) { /* not first in chain.... */
191 tmp
->right_entry
->left_entry
= (tmp
->left_entry
?
192 tmp
->left_entry
->right_entry
: NULL
);
194 tbl
->start
= (tmp
->left_entry
?tmp
->left_entry
->right_entry
:
201 operate_hash(hash
*tbl
, void (*ptr
)(), const char *usr_arg
)
203 hash_entry
*tmp
= tbl
->start
;
207 (*ptr
)(tmp
->data
, usr_arg
, tmp
->key
);
208 tmp
= tmp
->left_entry
;
215 operate_hash_addr(hash
*tbl
, void (*ptr
)(), const char *usr_arg
)
217 hash_entry
*tmp
= tbl
->start
;
221 (*ptr
)(&(tmp
->data
), usr_arg
, tmp
->key
);
222 tmp
= tmp
->left_entry
;
229 destroy_hash(hash
*tbl
, int (*ptr
)(), const char *usr_arg
)
231 hash_entry
* tmp
= tbl
->start
, * prev
;
235 (void) (*ptr
)(tmp
->data
, usr_arg
, tmp
->key
);
238 if (tbl
->hash_type
== String_Key
) {
242 tmp
= tmp
->left_entry
;
245 free((char *)tbl
->table
);
250 hash_string(const char *s
, long modulo
)
252 unsigned int result
= 0;
256 result
+= (*s
++ << i
++);
260 return ((int)(result
% modulo
));