File: table.c

package info (click to toggle)
posh 0.14.3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,108 kB
  • sloc: ansic: 14,639; xml: 1,604; perl: 964; sh: 110; makefile: 36
file content (110 lines) | stat: -rw-r--r-- 2,253 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * dynamic hashed associative table for commands and variables
 */

#include "sh.h"
#include <search.h>

static int tbl_compare(const void *pa, const void *pb) {
	return strcmp(((struct tbl *)pa)->name, ((struct tbl *)pb)->name);
}

void
transitional_tinit(struct table *tp, Area *ap)
{
	tp->areap = ap;
	tp->tbls = NULL;
	tp->root = NULL;
	tp->size = tp->nfree = 0;
}

struct tbl *
transitional_tsearch(void **tbl_root, const char *n)
{
	struct tbl *p, **q;
	unsigned int len;

	len = strlen(n) + 1;
	p = (struct tbl *) alloc(offsetof(struct tbl, name[0]) + len,
				 ATEMP);
	memcpy(p->name, n, len);

	q = tfind(p, (void **)tbl_root, tbl_compare);
	
	return q ? *q : NULL;
}

struct tbl *
transitional_tenter(void **tbl_root, const char *n, Area *ap)
{
	struct tbl *p, **q;
	unsigned int len;

	len = strlen(n) + 1;
	p = (struct tbl *) alloc(offsetof(struct tbl, name[0]) + len,
				 ap);
	p->flag = 0;
	p->type = 0;
	p->areap = ap;
	p->u2.field = 0;
	p->u.array = (struct tbl *)0;
	memcpy(p->name, n, len);

	q = (struct tbl **)tsearch((void *)p, (void **)tbl_root, tbl_compare);

	return *q;
}

void
transitional_tdelete(void **tbl_root, struct tbl *p)
{
	tdelete((void *)p, tbl_root, tbl_compare);
}

#ifdef PERF_DEBUG /* performance debugging */

void tprintinfo ARGS((struct table *tp));

void
tprintinfo(tp)
	struct table *tp;
{
	struct tbl *te;
	char *n;
	unsigned int h;
	int ncmp;
	int totncmp = 0, maxncmp = 0;
	int nentries = 0;
	struct tstate ts;

	shellf("table size %d, nfree %d\n", tp->size, tp->nfree);
	shellf("    Ncmp name\n");
	twalk(&ts, tp);
	while ((te = tnext(&ts))) {
		register struct tbl **pp, *p;

		h = hash(n = te->name);
		ncmp = 0;

		/* taken from tsearch() and added counter */
		for (pp = &tp->tbls[h & (tp->size-1)]; (p = *pp); pp--) {
			ncmp++;
			if (*p->name == *n && strcmp(p->name, n) == 0
			    && (p->flag&DEFINED))
				break; /* return p; */
			if (pp == tp->tbls) /* wrap */
				pp += tp->size;
		}
		shellf("    %4d %s\n", ncmp, n);
		totncmp += ncmp;
		nentries++;
		if (ncmp > maxncmp)
			maxncmp = ncmp;
	}
	if (nentries)
		shellf("  %d entries, worst ncmp %d, avg ncmp %d.%02d\n",
			nentries, maxncmp,
			totncmp / nentries,
			(totncmp % nentries) * 100 / nentries);
}
#endif /* PERF_DEBUG */