2 * dynamic hashed associative table for commands and variables
8 static int tbl_compare(const void *pa
, const void *pb
) {
9 return strcmp(((struct tbl
*)pa
)->name
, ((struct tbl
*)pb
)->name
);
13 transitional_tinit(struct table
*tp
, Area
*ap
)
18 tp
->size
= tp
->nfree
= 0;
22 transitional_tsearch(void **tbl_root
, const char *n
)
28 p
= (struct tbl
*) alloc(offsetof(struct tbl
, name
[0]) + len
,
30 memcpy(p
->name
, n
, len
);
32 q
= tfind(p
, (void **)tbl_root
, tbl_compare
);
38 transitional_tenter(void **tbl_root
, const char *n
, Area
*ap
)
44 p
= (struct tbl
*) alloc(offsetof(struct tbl
, name
[0]) + len
,
50 p
->u
.array
= (struct tbl
*)0;
51 memcpy(p
->name
, n
, len
);
53 q
= (struct tbl
**)tsearch((void *)p
, (void **)tbl_root
, tbl_compare
);
59 transitional_tdelete(void **tbl_root
, struct tbl
*p
)
61 tdelete((void *)p
, tbl_root
, tbl_compare
);
64 #ifdef PERF_DEBUG /* performance debugging */
66 void tprintinfo
ARGS((struct table
*tp
));
76 int totncmp
= 0, maxncmp
= 0;
80 shellf("table size %d, nfree %d\n", tp
->size
, tp
->nfree
);
81 shellf(" Ncmp name\n");
83 while ((te
= tnext(&ts
))) {
84 register struct tbl
**pp
, *p
;
86 h
= hash(n
= te
->name
);
89 /* taken from tsearch() and added counter */
90 for (pp
= &tp
->tbls
[h
& (tp
->size
-1)]; (p
= *pp
); pp
--) {
92 if (*p
->name
== *n
&& strcmp(p
->name
, n
) == 0
94 break; /* return p; */
95 if (pp
== tp
->tbls
) /* wrap */
98 shellf(" %4d %s\n", ncmp
, n
);
105 shellf(" %d entries, worst ncmp %d, avg ncmp %d.%02d\n",
108 (totncmp
% nentries
) * 100 / nentries
);
110 #endif /* PERF_DEBUG */