• use Jenkins’ one-at-a-time hash for mksh keytabs, as it has

much better avalanche and no known funnels
• improve comments
• fix some types (uint32_t for hash, size_t for sizes)
• optimise ktsort()

no functional change, I think
This commit is contained in:
tg 2009-08-28 18:54:01 +00:00
parent 8f937ec71b
commit ca1f967a45
7 changed files with 63 additions and 55 deletions

6
exec.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.60 2009/08/08 13:08:49 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.61 2009/08/28 18:53:57 tg Exp $");
static int comexec(struct op *, struct tbl *volatile, const char **,
int volatile, volatile int *);
@ -800,7 +800,7 @@ shcomexec(const char **wp)
* is created if none is found.
*/
struct tbl *
findfunc(const char *name, unsigned int h, int create)
findfunc(const char *name, uint32_t h, int create)
{
struct block *l;
struct tbl *tp = NULL;
@ -899,7 +899,7 @@ struct tbl *
findcom(const char *name, int flags)
{
static struct tbl temp;
unsigned int h = hash(name);
uint32_t h = hash(name);
struct tbl *tp = NULL, *tbi;
unsigned char insert = Flag(FTRACKALL); /* insert if not found */
char *fpath; /* for function autoloading */

View File

@ -25,7 +25,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.120 2009/08/08 13:08:50 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.121 2009/08/28 18:53:58 tg Exp $");
#if HAVE_KILLPG
/*
@ -1130,7 +1130,7 @@ c_alias(const char **wp)
const char *alias = *wp, *val, *newval;
char *xalias = NULL;
struct tbl *ap;
int h;
uint32_t h;
if ((val = cstrchr(alias, '='))) {
strndupx(xalias, alias, val++ - alias, ATEMP);

4
lex.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.89 2009/07/06 15:06:23 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.90 2009/08/28 18:53:58 tg Exp $");
/*
* states while lexing word
@ -909,7 +909,7 @@ yylex(int cf)
if (*ident != '\0' && (cf&(KEYWORD|ALIAS))) {
struct tbl *p;
int h = hash(ident);
uint32_t h = hash(ident);
/* { */
if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) &&

68
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.137 2009/08/08 13:08:51 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.138 2009/08/28 18:53:59 tg Exp $");
extern char **environ;
@ -148,7 +148,8 @@ main(int argc, const char *argv[])
initkeywords();
/* define built-in commands */
ktinit(&builtins, APERM, 64); /* must be 2^n (currently 44 builtins) */
ktinit(&builtins, APERM,
/* must be 80% of 2^n (currently 44 builtins) */ 64);
for (i = 0; mkshbuiltins[i].name != NULL; i++)
builtin(mkshbuiltins[i].name, mkshbuiltins[i].func);
@ -1233,36 +1234,36 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist)
#define INIT_TBLS 8 /* initial table size (power of 2) */
static void texpand(struct table *, int);
static void texpand(struct table *, size_t);
static int tnamecmp(const void *, const void *);
unsigned int
hash(const char *n)
/* Bob Jenkins' one-at-a-time hash */
uint32_t
hash(const char *cp)
{
unsigned int h = 0;
register uint32_t h = 0;
register uint8_t c;
register const uint8_t *bp = (const uint8_t *)cp;
while (*n != '\0')
h = 2*h + *n++;
return (h * 32821); /* scatter bits */
}
while ((c = *bp++)) {
h += c;
h += h << 10;
h ^= h >> 6;
}
void
ktinit(struct table *tp, Area *ap, int tsize)
{
tp->areap = ap;
tp->tbls = NULL;
tp->size = tp->nfree = 0;
if (tsize)
texpand(tp, tsize);
h += h << 3;
h ^= h >> 11;
h += h << 15;
return (h);
}
static void
texpand(struct table *tp, int nsize)
texpand(struct table *tp, size_t nsize)
{
int i;
size_t i, osize = tp->size;
struct tbl *tblp, **p;
struct tbl **ntblp, **otblp = tp->tbls;
int osize = tp->size;
ntblp = alloc(nsize * sizeof(struct tbl *), tp->areap);
for (i = 0; i < nsize; i++)
@ -1288,11 +1289,19 @@ texpand(struct table *tp, int nsize)
afree(otblp, tp->areap);
}
/* table */
/* name to enter */
/* hash(n) */
void
ktinit(struct table *tp, Area *ap, size_t tsize)
{
tp->areap = ap;
tp->tbls = NULL;
tp->size = tp->nfree = 0;
if (tsize)
texpand(tp, tsize);
}
/* table, name (key) to search for, hash(n) */
struct tbl *
ktsearch(struct table *tp, const char *n, unsigned int h)
ktsearch(struct table *tp, const char *n, uint32_t h)
{
struct tbl **pp, *p;
@ -1311,11 +1320,9 @@ ktsearch(struct table *tp, const char *n, unsigned int h)
return (NULL);
}
/* table */
/* name to enter */
/* hash(n) */
/* table, name (key) to enter, hash(n) */
struct tbl *
ktenter(struct table *tp, const char *n, unsigned int h)
ktenter(struct table *tp, const char *n, uint32_t h)
{
struct tbl **pp, *p;
int len;
@ -1387,7 +1394,8 @@ ktsort(struct table *tp)
p = alloc((tp->size + 1) * sizeof(struct tbl *), ATEMP);
sp = tp->tbls; /* source */
dp = p; /* dest */
for (i = 0; i < (size_t)tp->size; i++)
i = (size_t)tp->size;
while (i--)
if ((*dp = *sp++) != NULL && (((*dp)->flag & DEFINED) ||
((*dp)->flag & ARRAY)))
dp++;

12
sh.h
View File

@ -134,7 +134,7 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.323 2009/08/28 18:33:05 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.324 2009/08/28 18:53:59 tg Exp $");
#endif
#define MKSH_VERSION "R39 2009/08/08"
@ -1371,7 +1371,7 @@ int glob_str(char *, XPtrV *, int);
/* exec.c */
int execute(struct op * volatile, volatile int, volatile int * volatile);
int shcomexec(const char **);
struct tbl *findfunc(const char *, unsigned int, int);
struct tbl *findfunc(const char *, uint32_t, int);
int define(const char *, struct op *);
void builtin(const char *, int (*)(const char **));
struct tbl *findcom(const char *, int);
@ -1538,10 +1538,10 @@ void coproc_write_close(int);
int coproc_getfd(int, const char **);
void coproc_cleanup(int);
struct temp *maketemp(Area *, Temp_type, struct temp **);
unsigned int hash(const char *);
void ktinit(struct table *, Area *, int);
struct tbl *ktsearch(struct table *, const char *, unsigned int);
struct tbl *ktenter(struct table *, const char *, unsigned int);
uint32_t hash(const char *);
void ktinit(struct table *, Area *, size_t);
struct tbl *ktsearch(struct table *, const char *, uint32_t);
struct tbl *ktenter(struct table *, const char *, uint32_t);
#define ktdelete(p) do { p->flag = 0; } while (/* CONSTCOND */ 0)
void ktwalk(struct tstate *, struct table *);
struct tbl *ktnext(struct tstate *);

11
syn.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.38 2009/06/11 12:42:20 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.39 2009/08/28 18:54:00 tg Exp $");
struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */
@ -696,10 +696,10 @@ block(int type, struct op *t1, struct op *t2, char **wp)
return (t);
}
const struct tokeninfo {
const struct tokeninfo {
const char *name;
short val;
short reserved;
short val;
short reserved;
} tokentab[] = {
/* Reserved words */
{ "if", IF, true },
@ -739,7 +739,8 @@ initkeywords(void)
struct tokeninfo const *tt;
struct tbl *p;
ktinit(&keywords, APERM, 32); /* must be 2^n (currently 20 keywords) */
ktinit(&keywords, APERM,
/* must be 80% of 2^n (currently 20 keywords) */ 32);
for (tt = tokentab; tt->name; tt++) {
if (tt->reserved) {
p = ktenter(&keywords, tt->name, hash(tt->name));

13
var.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.77 2009/08/08 13:08:53 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.78 2009/08/28 18:54:01 tg Exp $");
/*
* Variables
@ -125,7 +125,8 @@ initvar(void)
int i;
struct tbl *tp;
ktinit(&specials, APERM, 16); /* must be 2^n (currently 12 specials) */
ktinit(&specials, APERM,
/* must be 80% of 2^n (currently 12 specials) */ 16);
for (i = 0; names[i].name; i++) {
tp = ktenter(&specials, names[i].name, hash(names[i].name));
tp->flag = DEFINED|ISSET;
@ -171,9 +172,8 @@ global(const char *n)
struct block *l = e->loc;
struct tbl *vp;
int c;
unsigned int h;
bool array;
uint32_t val;
uint32_t h, val;
/* Check to see if this is an array */
n = array_index_calc(n, &array, &val);
@ -252,9 +252,8 @@ local(const char *n, bool copy)
{
struct block *l = e->loc;
struct tbl *vp;
unsigned int h;
bool array;
uint32_t val;
uint32_t h, val;
/* Check to see if this is an array */
n = array_index_calc(n, &array, &val);
@ -889,7 +888,7 @@ makenv(void)
(vp->flag&(ISSET|EXPORT)) == (ISSET|EXPORT)) {
struct block *l2;
struct tbl *vp2;
unsigned int h = hash(vp->name);
uint32_t h = hash(vp->name);
/* unexport any redefined instances */
for (l2 = l->next; l2 != NULL; l2 = l2->next) {