view ueda/libueda/hashmcl.c @ 139:bf188727e606

donl-rename-parts reader: no tEDAx-style escapes
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 07 Sep 2020 04:25:11 +0000
parents c91e7a30fab3
children
line wrap: on
line source

/*
 * MCL hash table logic
 *
 * This module implements construction and use of a hash table indexing
 * the MCL components by refdes.  It facilitates checking the MCL for
 * duplicate refdes errors and fast component lookups.
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "mcl.h"

extern struct component components[];
extern int ncomponents;

#define	HASH_SIZE	1103

static struct component *mclhashtab[HASH_SIZE];

static int
hash_refdes(str)
	char *str;
{
	register u_long accum;
	register char *cp;
	register int c;

	for (cp = str, accum = 0; c = *cp; cp++) {
		accum <<= 4;
		accum |= c & 0x0F;
	}
	return(accum % HASH_SIZE);
}

hash_MCL()
{
	register struct component *comp, *hc, **hcp;
	int i;
	int errflag = 0, errstat = 0;

	for (comp = components, i = 0; i < ncomponents; comp++, i++) {
		hcp = mclhashtab + hash_refdes(comp->name);
		for (; hc = *hcp; hcp = &hc->nextinhash)
			if (!strcmp(comp->name, hc->name)) {
				fprintf(stderr,
					"%s: duplicate refdes in the MCL\n",
					comp->name);
				errflag = 1;
				break;
			}
		if (errflag) {
			errflag = 0;
			errstat = -1;
		} else
			*hcp = comp;
	}
	if (errstat)
		exit(1);
}

report_mclhash_quality()
{
	int maxchain;
	register int hb, curchain;
	register struct component *comp;

	for (hb = 0, maxchain = 0; hb < HASH_SIZE; hb++) {
		for (comp = mclhashtab[hb], curchain = 0; comp;
		     comp = comp->nextinhash)
			curchain++;
		if (curchain > maxchain)
			maxchain = curchain;
	}
	printf("Total components: %d\n", ncomponents);
	printf("Longest hash chain: %d\n", maxchain);
}

struct component *
find_comp_by_refdes(refdes)
	register char *refdes;
{
	register struct component *comp;

	for (comp = mclhashtab[hash_refdes(refdes)]; comp;
	     comp = comp->nextinhash)
		if (!strcmp(comp->name, refdes))
			return(comp);
	return(NULL);
}