hash.c 3.5 KB


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libaudio.h>
#include "midiDmon.h"
#include "midiApp.h"
#include "midiGlobals.h"

#ifdef SYSEX_IMPL

#define M1		71
#define HASH_MIN_SIZE    0x1000

typedef struct {
    u32     oldOffset;
    u32     newOffset;
} ptrPair;


ALSymObj        **gHashTable;
int             gHashMask;


/* only valid when compacting the mirror */
u32             gNumHashMask;
ptrPair         *gNumHashTable;

int AllocNameHash(int numObjs)
{
    int     hashTblSize;

    if(gHashTable)
        free(gHashTable);
    
    hashTblSize = NameHashSize(numObjs);

    gHashTable = (ALSymObj**)calloc(hashTblSize,sizeof(ALSymObj *));
    if (!gHashTable)
    {
        fprintf(stderr, "%s: couldn't allocate memory for hash table\n",gAppName);
        return(MEMORY_NOT_OK);
    }

    return(MEMORY_OK);
}

/* This returns an integer hash value for a string. */
int HashName(char *str)
{
    char c;
    int h = 0;
    while ((c = *str++) != '\0')
        h = (h * M1 + (int) c);

    return(h);
}

int AddHashName(char *str, ALSymObj *obj)
{
    int h = HashName(str);

    while (1)
    {
        h &= gHashMask;
        
        if (!(int)gHashTable[h])
        {
            gHashTable[h] = obj;
            return(h);
        }
        else
            h++; /* try again */
    }
}

ALSymObj *MatchHashName(char *name)
{
    char            *str;
    ALSymObj        *entry;
    int             h;

    h = HashName(name);
    
    while (1)
    {
        h &= gHashMask;
        entry = gHashTable[h];
        
        if (entry == NULL)
            return 0;

        str = (char *)&gNameBuffer[entry->SFObj.stringOffset];
        if (strcmp(name, str) == 0)
            return(entry);
        else
            h++;   /* try again */
    }
}

int NameHashSize(int numObjs)
{
    int     size = HASH_MIN_SIZE;
    int     hashSize =(int)( numObjs * 1.5);

    while(hashSize > size)
        size = size << 1;

    gHashMask = size - 1;
    
    return size;
}


int AllocNumHash(int numObj)
{
    int     hashSize;
    
    hashSize = NumHashSize(numObj);
    gNumHashTable = (ptrPair*)calloc(hashSize,sizeof(ptrPair));
    if(!gNumHashTable)
    {
        fprintf(stderr,"%s: Unable to allocate mememory for number hash table\n",gAppName);
        return(MEMORY_NOT_OK);
    }

    return(MEMORY_OK);
}

void DeallocNumHash(void)
{
    free(gNumHashTable);
}

    
int AddNumHash(u32 oldoffset, u32 newoffset)
{
    
    int h;

    if(oldoffset==0)
        oldoffset=1;

    h = oldoffset;
    
    while (1)
    {
        h &= gNumHashMask;

        if (!(int)gNumHashTable[h].oldOffset)
        {
            gNumHashTable[h].oldOffset = oldoffset;
            gNumHashTable[h].newOffset = newoffset;
            return(h);
        }
        else
            h++; /* try again */
    }
}

u32 MatchNumHash(u32 oldOffset)
{
    int     h;
    
    if(oldOffset==0)
        oldOffset = 1;
    
    h = oldOffset;

    while (1)
    {
        h &= gNumHashMask;
        if(!gNumHashTable[h].oldOffset)
        {
            fprintf(stderr,"%s: Didn't match hash number! %d\n",gAppName,oldOffset);
            return 0;
        }
        if (gNumHashTable[h].oldOffset == oldOffset)
            return(gNumHashTable[h].newOffset);
        else
            h++;   /* try again */
    }
}    

int NumHashSize(int numObjs)
{
    int     size = HASH_MIN_SIZE;
    int     HashSize =(int)( numObjs * 2);

    while(HashSize > size)
        size = size << 1;

    gNumHashMask = size - 1;
    
    return size;
}

#endif /* SYSEX_IMPL */