home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
pcmag
/
vol8n08.arc
/
SRCHHASH.C
< prev
next >
Wrap
Text File
|
1988-12-20
|
4KB
|
120 lines
/*
SRCHHASH.C Searches datafile and hash table created by MAKEHASH.C
Copyright (C) 1988 Ziff Communications Co.
PC Magazine * Ray Duncan
The user is prompted to enter a search key. A hash code
is generated and is used to probe the hash table stored in
the file TESTFILE.HSH. The record number, if any, found
in the hash table is used to read a record from TESTFILE.DAT.
Collisions are resolved by adding a constant increment
to the hashcode and wrapping when necessary until the
desired record or an empty hash table position is found.
Each record in TESTFILE.DAT is RSIZE bytes long. The size
of the hash table is determined by the constant HASHSIZE.
The incrementing value for linear probing is HASHINCR.
All manifest constants and structures must be synchronized
with MAKEHASH.C.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#define RSIZE 64 /* fixed record size */
#define HASHSIZE 1024 /* hash table size, should
be power of 2 */
#define HASHINCR 7 /* incrementing value for
linear probes of hash table */
int hashtab[HASHSIZE]; /* hash table read here */
int hashcode(char *); /* function prototypes */
main()
{
int i; /* scratch variable */
int fhdf, fhht; /* file handles */
int inspected; /* number of hash table
entries inspected */
long fsize; /* size of file in bytes */
int frecs; /* number of records in file */
char key[80]; /* key entered by user */
char rec[RSIZE]; /* scratch record buffer */
/* open all files */
fhdf = open("TESTFILE.DAT", O_RDONLY | O_BINARY);
fhht = open("TESTFILE.HSH", O_RDONLY | O_BINARY);
if((fhdf == -1) || (fhht == -1))
{
puts("\nMissing data file or hash table file.");
exit(1);
}
fsize = lseek(fhdf, 0L, SEEK_END); /* find file size */
frecs = fsize / RSIZE; /* calculate number of records */
printf("\nTESTFILE.DAT contains %ld bytes, %d records.", fsize, frecs);
/* read hash table into memory */
read(fhht, (char *) hashtab, sizeof(hashtab));
close(fhht); /* and release its handle */
while(1)
{
printf("\n\nEnter key: "); /* prompt user and */
gets(key); /* input record key */
if(key[0] == 0) break; /* terminate if empty line */
inspected = 1; /* initialize inspection count */
i = hashcode(key); /* calculate hash code */
while(hashtab[i] != -1) /* inspect datafile records */
{
lseek(fhdf, (long) (RSIZE * hashtab[i]), SEEK_SET);
read(fhdf, rec, RSIZE);
if(strcmp(rec, key) == 0) /* if match, we're done */
break;
i += HASHINCR; /* otherwise bump hashcode */
if(i >= HASHSIZE) /* wrap hashcode if necessary */
i -= HASHSIZE;
inspected++; /* count table inspections */
}
if(hashtab[i] == -1) printf("\nRecord not found");
else printf("\nContents of record %d: %s", hashtab[i], rec);
printf(" --- %d hash table entries inspected", inspected);
}
close(fhdf); /* release data file handle */
}
/*
Calculate hash code from supplied ASCII string. Hash
code is clamped to the range {0 ... HASHSIZE-1}. Collisions
are resolved elsewhere.
*/
int hashcode(char *kptr)
{
int i, j = 0; /* scratch variables */
/* sum characters of key */
for(i = 0; i < strlen(kptr); i++) j = (j*2) + kptr[i];
return(j & (HASHSIZE - 1)); /* clamp hash code */
}