Commit 8cb8ba14 authored by Ken Thompson's avatar Ken Thompson

more on dynamic hash in compound literals.

thanks to vskrap, andrey mirtchovski,
and Eoghan Sherry.

R=rsc
CC=golang-dev
https://golang.org/cl/3245041
parent b1fd0860
...@@ -1809,14 +1809,11 @@ indexdup(Node *n, Node *hash[], ulong nhash) ...@@ -1809,14 +1809,11 @@ indexdup(Node *n, Node *hash[], ulong nhash)
} }
static int static int
prime(ulong h) prime(ulong h, ulong sr)
{ {
ulong n, sr; ulong n;
sr = h; for(n=3; n<=sr; n+=2)
for(n=0; n<3; n++)
sr = (sr + h/sr)/2;
for(n=3; n<sr; n+=2)
if(h%n == 0) if(h%n == 0)
return 0; return 0;
return 1; return 1;
...@@ -1825,20 +1822,37 @@ prime(ulong h) ...@@ -1825,20 +1822,37 @@ prime(ulong h)
static ulong static ulong
inithash(Node *n, Node ***hash, Node **autohash, ulong nautohash) inithash(Node *n, Node ***hash, Node **autohash, ulong nautohash)
{ {
ulong h; ulong h, sr;
NodeList *ll; NodeList *ll;
int i;
// count the number of entries
h = 0; h = 0;
for(ll=n->list; ll; ll=ll->next) for(ll=n->list; ll; ll=ll->next)
h++; h++;
h = 9*h/8;
// if the auto hash table is
// large enough use it.
if(h <= nautohash) { if(h <= nautohash) {
*hash = autohash; *hash = autohash;
memset(*hash, 0, nautohash * sizeof(**hash)); memset(*hash, 0, nautohash * sizeof(**hash));
return nautohash; return nautohash;
} }
while(!prime(h))
h++; // make hash size odd and 12% larger than entries
h += h/8;
h |= 1;
// calculate sqrt of h
sr = h/2;
for(i=0; i<5; i++)
sr = (sr + h/sr)/2;
// check for primeality
while(!prime(h, sr))
h += 2;
// build and return a throw-away hash table
*hash = mal(h * sizeof(**hash)); *hash = mal(h * sizeof(**hash));
memset(*hash, 0, h * sizeof(**hash)); memset(*hash, 0, h * sizeof(**hash));
return h; return h;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment