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

#ifndef _PRIVATE_HASH_H
#define	_PRIVATE_HASH_H

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

#include "VMS_impl/VMS_primitive_data_types.h"
#include "VMS_impl/Services_Offered_by_VMS/Memory_Handling/vmalloc.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];
    int  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
 { int         tableSz;
   int         numEntries;
   HashEntry* *entries;
   int32       hashMask;
   int32       prevHash;
   FreeEntryContentFnPtr freeEntryContentFn;
 }
HashTable;


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

int          putEntryIntoTable( HashEntry *entry, HashTable *table);
int          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 );

int        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 */

