/*
 *  Copyright 2009 OpenSourceResearchInstitute.org
 *  Licensed under GNU General Public License version 2
 *
 * Author: seanhalle@yahoo.com
 */

#ifndef _PRHASH_H
#define	_PRHASH_H

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

#include <PR__include/PR__primitive_data_types.h>

//=====================  defines  =====================
#define TRUE     1
#define FALSE    0

#define DEFAULT_HASH_TABLE_SIZE 1 << 10
#define DEFAULT_POWER_OF_2_TABLE_SIZE 10


//=====================  structs  =====================
union hashkey_t{
    char hashable[8];
    int32 parts[2];
};

typedef union hashkey_t hashkey_t;

typedef struct _HashEntry HashEntry;

struct _HashEntry
 {
   char       *key;
   void       *content;
   HashEntry  *next;
 };

typedef void (*FreeEntryContentFnPtr)    ( void * );

typedef struct
 { int32       tableSz;
   int32       numEntries;
   HashEntry* *entries;
   int32       hashMask;
   int32       prevHash;
   FreeEntryContentFnPtr freeEntryContentFn;
 }
HashTable;


//===========================================================================
//   Public functions
HashTable   *makeHashTable( int numHashSlots, FreeEntryContentFnPtr freeFn );

int32        putEntryIntoTable( HashEntry *entry, HashTable *table);
int32        addValueIntoTable( char* key, void *value, HashTable *table);
HashEntry   *getEntryFromTable( char *key, HashTable *table );
void        *getValueFromTable( char *key, HashTable *table );

bool8        deleteEntryFromTable( char *key, HashTable *table );
bool8        deleteThisEntryFromTable( HashEntry *entry, HashTable *table );
bool8        deleteEntrysValueInTable( char *key, HashTable *table );
bool8        deleteEntryFromTableAndFreeValue( char *key, HashTable *table );
void         freeHashTable( HashTable *table );
//char        *paramBagToString( ParamBag * bag )

//================= Same Fns, but for 32b array key hash fn ================
HashTable *makeHashTable32(int32 powerOf2OfSz, FreeEntryContentFnPtr freeFn);
HashTable *makeDefaultSizeHashTable32( FreeEntryContentFnPtr freeFn );

int32      putEntryIntoTable32( HashEntry *entry, HashTable *table);
HashEntry *addValueIntoTable32( uint32 key[], void *value, HashTable *table);
HashEntry *getEntryFromTable32( uint32 key[], HashTable *table );
void      *getValueFromTable32( uint32 key[], HashTable *table );

bool32     deleteEntryFromTable32( uint32 key[], HashTable *table );

//===========================================================================
//   Internal functions
void         freeHashEntryUsing( HashEntry *entry, HashTable *table );
unsigned int hashThisKey( char *s, int hashSz );
void         nullOutTablesArray( HashTable *table );
void         doubleTableSize( HashTable *table );
void         freeHashEntryButNotContent( HashEntry *entry );

uint32 
jenkHash32( const uint32  *key,     /* array of uint32 values */
                   int32   length);  /* num uint32 in the key */
        
#endif	/* _PRIVATE_HASH_H */

