Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "all.h"

#define STRHASH 509     /* prime */

static Strnode *        stab[STRHASH];

static long     hashfun(void*);
static Strnode* nalloc(int);

char *
strfind(char *a)
{
        Strnode **bin, *x, *xp;

        bin = &stab[hashfun(a) % STRHASH];
        for(xp=0, x=*bin; x; xp=x, x=x->next)
                if(x->str[0] == a[0] && strcmp(x->str, a) == 0)
                        break;
        if(x == 0)
                return 0;
        if(xp){
                xp->next = x->next;
                x->next = *bin;
                *bin = x;
        }
        return x->str;
}

char *
strstore(char *a)
{
        Strnode **bin, *x, *xp;
        int n;

        bin = &stab[hashfun(a) % STRHASH];
        for(xp=0, x=*bin; x; xp=x, x=x->next)
                if(x->str[0] == a[0] && strcmp(x->str, a) == 0)
                        break;
        if(x == 0){
                n = strlen(a)+1;
                x = nalloc(n);
                memmove(x->str, a, n);
                x->next = *bin;
                *bin = x;
        }else if(xp){
                xp->next = x->next;
                x->next = *bin;
                *bin = x;
        }
        return x->str;
}

void
strprint(int fd)
{
        Strnode **bin, *x;

        for(bin = stab; bin < stab+STRHASH; bin++)
                for(x=*bin; x; x=x->next)
                        fprint(fd, "%ld %s\n", bin-stab, x->str);
}

static long
hashfun(void *v)
{
        ulong a = 0, b;
        uchar *s = v;

        while(*s){
                a = (a << 4) + *s++;
                if(b = a&0xf0000000){   /* assign = */
                        a ^= b >> 24;
                        a ^= b;
                }
        }
        return a;
}

#define STRSIZE 1000

static Strnode *
nalloc(int n)   /* get permanent storage for Strnode */
{
        static char *curstp;
        static int nchleft;
        int k;
        char *p;

        if(n < 4)
                n = 4;
        else if(k = n&3)        /* assign = */
                n += 4-k;
        n += sizeof(Strnode)-4;
        if(n > nchleft){
                nchleft = STRSIZE;
                while(nchleft < n)
                        nchleft *= 2;
                if((curstp = malloc(nchleft)) == 0)
                        panic("malloc(%d) failed in nalloc\n", nchleft);
        }
        p = curstp;
        curstp += n;
        nchleft -= n;
        return (Strnode*)p;
}