du(1): -A should not affect block size
[unleashed.git] / usr / src / cmd / sgs / link_audit / common / hash.c
blobfa03dab22207c8b271241dd4044b057a1892ffd4
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <synch.h>
29 #include <memory.h>
30 #include "hash.h"
32 static int hash_string(const char *, long);
34 hash *
35 make_hash(size_t size)
37 hash *ptr;
39 ptr = malloc(sizeof (*ptr));
40 ptr->size = size;
41 ptr->table = malloc((size_t)(sizeof (hash_entry *) * size));
42 (void) memset((char *)ptr->table, 0, sizeof (hash_entry *) * size);
43 ptr->start = NULL;
44 ptr->hash_type = String_Key;
45 return (ptr);
48 hash *
49 make_ihash(size_t size)
51 hash *ptr;
53 ptr = malloc(sizeof (*ptr));
54 ptr->size = size;
55 ptr->table = malloc(sizeof (hash_entry *) * size);
56 (void) memset((char *)ptr->table, 0, sizeof (hash_entry *) * size);
57 ptr->start = NULL;
58 ptr->hash_type = Integer_Key;
59 return (ptr);
62 char **
63 get_hash(hash *tbl, char *key)
65 long bucket;
66 hash_entry *tmp, *new;
68 if (tbl->hash_type == String_Key) {
69 tmp = tbl->table[bucket = hash_string(key, tbl->size)];
70 } else {
71 tmp = tbl->table[bucket = labs((long)key) % tbl->size];
74 if (tbl->hash_type == String_Key) {
75 while (tmp != NULL) {
76 if (strcmp(tmp->key, key) == 0) {
77 return (&tmp->data);
79 tmp = tmp->next_entry;
81 } else {
82 while (tmp != NULL) {
83 if (tmp->key == key) {
84 return (&tmp->data);
86 tmp = tmp->next_entry;
91 * not found....
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;
102 tbl->start = new;
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 */
110 return (&new->data);
113 char **
114 find_hash(hash *tbl, const char *key)
116 hash_entry *tmp;
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) {
122 return (&tmp->data);
125 } else {
126 tmp = tbl->table[labs((long)key) % tbl->size];
127 for (; tmp != NULL; tmp = tmp->next_entry) {
128 if (tmp->key == key) {
129 return (&tmp->data);
133 return (NULL);
136 char *
137 del_hash(hash *tbl, const char *key)
139 ulong_t bucket;
140 hash_entry * tmp, * prev = NULL;
142 if (tbl->hash_type == String_Key) {
143 bucket = hash_string(key, tbl->size);
144 } else {
145 bucket = labs((long)key) % tbl->size;
148 if ((tmp = tbl->table[bucket]) == NULL) {
149 return (NULL);
150 } else {
151 if (tbl->hash_type == String_Key) {
152 while (tmp != NULL) {
153 if (strcmp(tmp->key, key) == 0) {
154 break; /* found item to delete ! */
156 prev = tmp;
157 tmp = tmp->next_entry;
159 } else {
160 while (tmp != NULL) {
161 if (tmp->key == key) {
162 break;
164 prev = tmp;
165 tmp = tmp->next_entry;
168 if (tmp == NULL) {
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) {
179 free(tmp->key);
181 if (prev != NULL) {
182 prev->next_entry = tmp->next_entry;
183 } else {
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);
193 } else {
194 tbl->start = (tmp->left_entry ?tmp->left_entry->right_entry:
195 NULL);
197 return (tmp->data);
200 size_t
201 operate_hash(hash *tbl, void (*ptr)(), const char *usr_arg)
203 hash_entry *tmp = tbl->start;
204 size_t c = 0;
206 while (tmp) {
207 (*ptr)(tmp->data, usr_arg, tmp->key);
208 tmp = tmp->left_entry;
209 c++;
211 return (c);
214 size_t
215 operate_hash_addr(hash *tbl, void (*ptr)(), const char *usr_arg)
217 hash_entry *tmp = tbl->start;
218 size_t c = 0;
220 while (tmp) {
221 (*ptr)(&(tmp->data), usr_arg, tmp->key);
222 tmp = tmp->left_entry;
223 c++;
225 return (c);
228 void
229 destroy_hash(hash *tbl, int (*ptr)(), const char *usr_arg)
231 hash_entry * tmp = tbl->start, * prev;
233 while (tmp) {
234 if (ptr) {
235 (void) (*ptr)(tmp->data, usr_arg, tmp->key);
238 if (tbl->hash_type == String_Key) {
239 free(tmp->key);
241 prev = tmp;
242 tmp = tmp->left_entry;
243 free((char *)prev);
245 free((char *)tbl->table);
246 free(tbl);
249 static int
250 hash_string(const char *s, long modulo)
252 unsigned int result = 0;
253 int i = 1;
255 while (*s != '\0') {
256 result += (*s++ << i++);
259 /* LINTED */
260 return ((int)(result % modulo));