1*7836SJohn.Forte@Sun.COM /* 2*7836SJohn.Forte@Sun.COM * CDDL HEADER START 3*7836SJohn.Forte@Sun.COM * 4*7836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the 5*7836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License"). 6*7836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License. 7*7836SJohn.Forte@Sun.COM * 8*7836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*7836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions 11*7836SJohn.Forte@Sun.COM * and limitations under the License. 12*7836SJohn.Forte@Sun.COM * 13*7836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*7836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*7836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*7836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*7836SJohn.Forte@Sun.COM * 19*7836SJohn.Forte@Sun.COM * CDDL HEADER END 20*7836SJohn.Forte@Sun.COM */ 21*7836SJohn.Forte@Sun.COM /* 22*7836SJohn.Forte@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*7836SJohn.Forte@Sun.COM * Use is subject to license terms. 24*7836SJohn.Forte@Sun.COM */ 25*7836SJohn.Forte@Sun.COM 26*7836SJohn.Forte@Sun.COM #include <string.h> 27*7836SJohn.Forte@Sun.COM #include <stdlib.h> 28*7836SJohn.Forte@Sun.COM #include <sys/nsctl/nsc_hash.h> 29*7836SJohn.Forte@Sun.COM 30*7836SJohn.Forte@Sun.COM #define HASH_PRIME 2039 31*7836SJohn.Forte@Sun.COM 32*7836SJohn.Forte@Sun.COM static int calc_hash(const char *); 33*7836SJohn.Forte@Sun.COM 34*7836SJohn.Forte@Sun.COM hash_node_t ** 35*7836SJohn.Forte@Sun.COM nsc_create_hash() 36*7836SJohn.Forte@Sun.COM { 37*7836SJohn.Forte@Sun.COM hash_node_t **hash; 38*7836SJohn.Forte@Sun.COM 39*7836SJohn.Forte@Sun.COM hash = (hash_node_t **)calloc(HASH_PRIME, sizeof (hash_node_t *)); 40*7836SJohn.Forte@Sun.COM return (hash); 41*7836SJohn.Forte@Sun.COM } 42*7836SJohn.Forte@Sun.COM 43*7836SJohn.Forte@Sun.COM int 44*7836SJohn.Forte@Sun.COM nsc_insert_node(hash_node_t **hash, void *data, const char *key) 45*7836SJohn.Forte@Sun.COM { 46*7836SJohn.Forte@Sun.COM int index; 47*7836SJohn.Forte@Sun.COM hash_node_t *node; 48*7836SJohn.Forte@Sun.COM 49*7836SJohn.Forte@Sun.COM node = (hash_node_t *)malloc(sizeof (hash_node_t)); 50*7836SJohn.Forte@Sun.COM if (!node) { 51*7836SJohn.Forte@Sun.COM return (-1); 52*7836SJohn.Forte@Sun.COM } 53*7836SJohn.Forte@Sun.COM node->key = strdup(key); 54*7836SJohn.Forte@Sun.COM node->data = data; 55*7836SJohn.Forte@Sun.COM 56*7836SJohn.Forte@Sun.COM /* 57*7836SJohn.Forte@Sun.COM * possible enhancement would be to search 58*7836SJohn.Forte@Sun.COM * in this index for a duplicate 59*7836SJohn.Forte@Sun.COM */ 60*7836SJohn.Forte@Sun.COM index = calc_hash(key); 61*7836SJohn.Forte@Sun.COM node->next = hash[ index ]; 62*7836SJohn.Forte@Sun.COM hash[ index ] = node; 63*7836SJohn.Forte@Sun.COM 64*7836SJohn.Forte@Sun.COM return (0); 65*7836SJohn.Forte@Sun.COM } 66*7836SJohn.Forte@Sun.COM 67*7836SJohn.Forte@Sun.COM /* 68*7836SJohn.Forte@Sun.COM * lookup 69*7836SJohn.Forte@Sun.COM * 70*7836SJohn.Forte@Sun.COM * Description: 71*7836SJohn.Forte@Sun.COM * Searches the hash to find a node. 72*7836SJohn.Forte@Sun.COM * 73*7836SJohn.Forte@Sun.COM * Return values: 74*7836SJohn.Forte@Sun.COM * 0 if not found. 75*7836SJohn.Forte@Sun.COM * pointer to node if found. 76*7836SJohn.Forte@Sun.COM */ 77*7836SJohn.Forte@Sun.COM void * 78*7836SJohn.Forte@Sun.COM nsc_lookup(hash_node_t **hash, const char *key) 79*7836SJohn.Forte@Sun.COM { 80*7836SJohn.Forte@Sun.COM int index; 81*7836SJohn.Forte@Sun.COM hash_node_t *node; 82*7836SJohn.Forte@Sun.COM 83*7836SJohn.Forte@Sun.COM index = calc_hash(key); 84*7836SJohn.Forte@Sun.COM node = hash[ index ]; 85*7836SJohn.Forte@Sun.COM while (node) { 86*7836SJohn.Forte@Sun.COM if (strcmp(node->key, key) == 0) 87*7836SJohn.Forte@Sun.COM return (node->data); 88*7836SJohn.Forte@Sun.COM node = node->next; 89*7836SJohn.Forte@Sun.COM } 90*7836SJohn.Forte@Sun.COM return (0); 91*7836SJohn.Forte@Sun.COM } 92*7836SJohn.Forte@Sun.COM 93*7836SJohn.Forte@Sun.COM void * 94*7836SJohn.Forte@Sun.COM nsc_remove_node(hash_node_t **hash, char *key) 95*7836SJohn.Forte@Sun.COM { 96*7836SJohn.Forte@Sun.COM int index; 97*7836SJohn.Forte@Sun.COM hash_node_t *node, *prev; 98*7836SJohn.Forte@Sun.COM void *retval; 99*7836SJohn.Forte@Sun.COM 100*7836SJohn.Forte@Sun.COM index = calc_hash(key); 101*7836SJohn.Forte@Sun.COM if (!hash[ index ]) { 102*7836SJohn.Forte@Sun.COM return (0); 103*7836SJohn.Forte@Sun.COM } 104*7836SJohn.Forte@Sun.COM 105*7836SJohn.Forte@Sun.COM if (strcmp(hash[ index ]->key, key) == 0) { 106*7836SJohn.Forte@Sun.COM node = hash[ index ]; 107*7836SJohn.Forte@Sun.COM retval = node->data; 108*7836SJohn.Forte@Sun.COM hash[ index ] = hash[ index ]->next; 109*7836SJohn.Forte@Sun.COM free(node->key); 110*7836SJohn.Forte@Sun.COM free(node); 111*7836SJohn.Forte@Sun.COM return (retval); 112*7836SJohn.Forte@Sun.COM } 113*7836SJohn.Forte@Sun.COM prev = hash[ index ]; 114*7836SJohn.Forte@Sun.COM node = prev->next; 115*7836SJohn.Forte@Sun.COM while (node && (strcmp(node->key, key) != 0)) { 116*7836SJohn.Forte@Sun.COM prev = node; 117*7836SJohn.Forte@Sun.COM node = node->next; 118*7836SJohn.Forte@Sun.COM } 119*7836SJohn.Forte@Sun.COM 120*7836SJohn.Forte@Sun.COM /* did we find it? */ 121*7836SJohn.Forte@Sun.COM if (node) { 122*7836SJohn.Forte@Sun.COM prev->next = node->next; 123*7836SJohn.Forte@Sun.COM retval = node->data; 124*7836SJohn.Forte@Sun.COM free(node->key); 125*7836SJohn.Forte@Sun.COM free(node); 126*7836SJohn.Forte@Sun.COM return (retval); 127*7836SJohn.Forte@Sun.COM } 128*7836SJohn.Forte@Sun.COM return (0); 129*7836SJohn.Forte@Sun.COM } 130*7836SJohn.Forte@Sun.COM 131*7836SJohn.Forte@Sun.COM void 132*7836SJohn.Forte@Sun.COM nsc_remove_all(hash_node_t **hash, void (*callback)(void *)) 133*7836SJohn.Forte@Sun.COM { 134*7836SJohn.Forte@Sun.COM int i; 135*7836SJohn.Forte@Sun.COM hash_node_t *p, *next; 136*7836SJohn.Forte@Sun.COM 137*7836SJohn.Forte@Sun.COM for (i = 0; i < HASH_PRIME; i++) { 138*7836SJohn.Forte@Sun.COM p = hash[ i ]; 139*7836SJohn.Forte@Sun.COM while (p) { 140*7836SJohn.Forte@Sun.COM next = p->next; 141*7836SJohn.Forte@Sun.COM if (callback) { 142*7836SJohn.Forte@Sun.COM callback(p->data); 143*7836SJohn.Forte@Sun.COM } 144*7836SJohn.Forte@Sun.COM free(p->key); 145*7836SJohn.Forte@Sun.COM free(p); 146*7836SJohn.Forte@Sun.COM p = next; 147*7836SJohn.Forte@Sun.COM } 148*7836SJohn.Forte@Sun.COM } 149*7836SJohn.Forte@Sun.COM free(hash); 150*7836SJohn.Forte@Sun.COM } 151*7836SJohn.Forte@Sun.COM 152*7836SJohn.Forte@Sun.COM /* ---------------------------------------------------------------------- */ 153*7836SJohn.Forte@Sun.COM 154*7836SJohn.Forte@Sun.COM /* 155*7836SJohn.Forte@Sun.COM * Basic rotating hash, as per Knuth. 156*7836SJohn.Forte@Sun.COM */ 157*7836SJohn.Forte@Sun.COM static int 158*7836SJohn.Forte@Sun.COM calc_hash(const char *key) 159*7836SJohn.Forte@Sun.COM { 160*7836SJohn.Forte@Sun.COM unsigned int hash, i; 161*7836SJohn.Forte@Sun.COM int len = strlen(key); 162*7836SJohn.Forte@Sun.COM for (hash = len, i = 0; i < len; i++) { 163*7836SJohn.Forte@Sun.COM hash = (hash << 5) ^ (hash >> 27) ^ key[ i ]; 164*7836SJohn.Forte@Sun.COM } 165*7836SJohn.Forte@Sun.COM return (hash % HASH_PRIME); 166*7836SJohn.Forte@Sun.COM } 167