/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/*
* Compile time switches:
*
* MULT - use a multiplicative hashing function.
* DIV - use the remainder mod table size as a hashing function.
* CHAINED - use a linked list to resolve collisions.
* OPEN - use open addressing to resolve collisions.
* BRENT - use Brent's modification to improve the OPEN algorithm.
* SORTUP - CHAINED list is sorted in increasing order.
* SORTDOWN - CHAINED list is sorted in decreasing order.
* START - CHAINED list with entries appended at front.
* DRIVER - compile in a main program to drive the tests.
* DEBUG - compile some debugging printout statements.
* USCR - user supplied comparison routine.
*/
#include "lint.h"
#include <mtlib.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread.h>
#include <synch.h>
#include <search.h>
typedef char *POINTER;
#define SUCCEED 0
#define FALSE 0
#define repeat for (;;)
#define until(A) if (A) break;
#ifdef OPEN
#else
#ifndef CHAINED
#define OPEN
#endif
#endif
#ifdef MULT
#else
#ifndef DIV
#define MULT
#endif
#endif
#ifdef START
#else
#ifdef SORTUP
#endif
#endif
#ifdef USCR
extern int (* hcompar)();
#else
#endif
#ifdef MULT
#else
#ifdef DIV
static unsigned int hashd();
#endif
#endif
#ifdef CHAINED
} NODE;
#else
#ifdef OPEN
#endif
#endif
static unsigned int m; /* Log base 2 of length */
/*
* forward declarations
*/
#ifdef DRIVER
static void hdump();
main()
{
int i = 0; /* Data generator */
if (hcreate(5))
else {
}
repeat {
hdump();
printf("Enter a probe: ");
#ifdef DEBUG
#endif
} else {
}
}
}
printf("Table is full\n");
else {
printf("Success: ");
}
}
hdestroy();
goto start;
}
#endif
int
/* Minimum "size" for hash table */
{
unsigned int local_length;
unsigned int local_m;
if (size == 0)
return (FALSE);
local_m = 0; /* Log2 length */
while (unsize) {
unsize >>= 1;
local_length <<= 1;
local_m++;
}
table = local_table;
m = local_m;
return (local_table != NULL);
}
void
{
#ifdef CHAINED
int i;
for (i = 0; i < length; i++) {
p = table[i];
oldp = p;
p = p -> next;
/*
* This is a locking vs malloc() violation.
* Fortunately, it is not actually compiled.
*/
}
}
}
#endif
table = 0;
#ifdef OPEN
count = 0;
#endif
}
#ifdef OPEN
/*
* Hash search of a fixed-capacity table. Open addressing used to
* resolve collisions. Algorithm modified from Knuth, Volume 3,
* section 6.4, algorithm D. Labels flag corresponding actions.
*/
/* Find or insert the item into the table */
/* "item" to be inserted or found */
/* action: FIND or ENTER */
{
unsigned int i; /* Insertion index */
unsigned int c; /* Secondary probe displacement */
prcnt = 1;
/* D1: */
#ifdef DEBUG
printf("hash = %o\n", i);
#endif
/* D2: */
goto D6;
/* D3: */
#ifdef DEBUG
printf("hash2 = %o\n", c);
#endif
D4:
i = (i + c) % length; /* Advance to next slot */
prcnt++;
/* D5: */
goto D6;
else
goto D4;
#ifdef BRENT
/*
* Brent's variation of the open addressing algorithm. Do extra
* work during insertion to speed retrieval. May require switching
* of previously placed items. Adapted from Knuth, Volume 3, section
* 4.6 and Brent's article in CACM, volume 10, #2, February 1973.
*/
{
unsigned int j; /* Counts along main branch */
unsigned int k; /* Counts along secondary branch */
if (prcnt >= 3) {
for (j = 0; j < prcnt; j++) { /* Count along main branch */
for (k = 1; j+k <= r; k++) {
/* Count on secondary branch */
/* Secondary probe */
/* Improvement found */
r = j + k; /* Decrement upper bound */
/* Save secondeary index */
}
}
}
#ifdef DEBUG
printf("Switch curpos = %o, curj = %o, oldi = %o\n",
#endif
i = curj;
}
}
}
#endif
count++; /* Increment table occupancy count */
return (&table[i]); /* Address of item is returned */
}
#endif
#ifdef USCR
#ifdef DRIVER
static int
compare(a, b)
POINTER a;
POINTER b;
{
return (strcmp(a, b));
}
#endif
#endif
#ifdef CHAINED
#ifdef SORTUP
#else
#ifdef SORTDOWN
#else
#endif
#endif
{
NODE *p; /* Searches through the linked list */
NODE **q; /* Where to store the pointer to a new NODE */
unsigned int i; /* Result of hash */
prcnt = 1;
else
} else { /* List is not empty */
q = &table[i];
p = table[i];
prcnt++;
q = &(p->next);
p = p->next;
}
else { /* Item is not yet on list */
else
#ifdef START
#else
#endif
}
}
}
static ENTRY
{
/*
* This is a locking vs malloc() violation.
* Fortunately, it is not actually compiled.
*/
if (p != NULL) {
*last = p;
return (&(p->item));
} else
return (NULL);
}
#endif
#ifdef DIV
static unsigned int
{
}
#else
#ifdef MULT
/*
* NOTE: The following algorithm only works on machines where
* the results of multiplying two integers is the least
* significant part of the double word integer required to hold
* the result. It is adapted from Knuth, Volume 3, section 6.4.
*/
static unsigned int
/* "key" to be hashed */
{
}
/*
* Secondary hashing, for use with multiplicitive hashing scheme.
* Adapted from Knuth, Volume 3, section 6.4.
*/
static unsigned int
/* "key" is the string to be hashed */
{
}
#endif
#endif
/* PJ Weinberger's hash function */
static unsigned int
{
unsigned int h = 0;
unsigned int g;
unsigned char *p = (unsigned char *)key;
for (; *p; p++) {
h = (h << 4) + *p;
g = h & 0xf0000000;
if (g != 0) {
h ^= (g >> 24);
h ^= g;
}
}
return (h);
}
#ifdef DRIVER
static void
{
unsigned int i; /* Counts table slots */
#ifdef OPEN
#else
#ifdef CHAINED
NODE *a; /* Current Node on list */
#endif
#endif
for (i = 0; i < length; i++)
#ifdef OPEN
printf("%o.\t-,\t-,\t(NULL)\n", i);
else {
/* Save current probe count */
printf("%o.\t%d,\t%d,\t%s\n", i,
}
#else
#ifdef CHAINED
printf("%o.\t-,\t-,\t(NULL)\n", i);
else {
printf("%o.", i);
printf("\t%d,\t%#0.4x,\t%s\n",
}
#endif
#endif
}
#endif