/**********************************************************************
 * Copyright (c) 2005 Scapa Technologies Limited and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: 
 * Scapa Technologies Limited - Initial API and implementation
 *
 * Hoang M. Nguyen, Intel - Modified to support integer as key and (void *) as value
 *
 * $Id: hashtable.h,v 1.3 2005/06/14 18:19:15 hnguyen Exp $
 *
 **********************************************************************/

#ifndef __HASHTABLE_H__
#define __HASHTABLE_H__

#include "tptp/system.h"
#include "tptp/TPTPTypes.h"

#ifdef __cplusplus
extern "C" {
#endif


/** type of hash entry */
typedef  void *  Entry_value_ptr_t ;

/** structure of an entry */
typedef struct {
	long int          hash;
	tptp_uint32       key;
	Entry_value_ptr_t pValue;
	void * next;
} Entry;


/** hash table structure */
typedef struct {
	Entry**	table;
	int table_len;
	int count;
	int threshold;
	XMutex mutex;

} HashTable;


/**
 *********************************************************
 *
 * @brief
 *    return indicator whether a given hash table contains the entry
 *    of a given key
 *
 * @return
 *    0 -       does not contain
 *    nonzero - yes, it contains
 *
 * @note 
 *    SYNCHRONIZED
 *
 *********************************************************/
BOOL containsKey(HashTable* table, tptp_uint32 key);


/**
 *********************************************************
 *
 * @brief
 *    return the list of all keys in the hash table to the given array
 *
 * @return
 *    the number of keys in the hash table
 *
 * @note 
 *    SYNCHRONIZED
 *
 *********************************************************/
int tableKeysAsList(HashTable* table, tptp_uint32 list[], int list_size);


/**
 *********************************************************
 *
 * @brief
 *    Create the hash table.
 *    This is a dynamic table where the size is automatically expanding
 *    to accommodate the increasing number of entries.
 *
 * @return
 *    The pointer to the newly created hash table
 *
 * @note 
 *    UNSYNCHRONIZED
 *
 *********************************************************/
HashTable* tableCreate();


/**
 *********************************************************
 *
 * @brief
 *    delete the given hash table.
 *    Note that this function will also free all storages holding
 *    the entry as well as the value.
 *
 * @note 
 *    UNSYNCHRONIZED
 *
 *********************************************************/
void tableDelete(HashTable* hasht);


/**
 *********************************************************
 *
 * @brief
 *    clear the hash table by freeing all entries it contains.
 *    Note that this function will also free all storages holding
 *    the entry as well as the value.
 *
 * @note 
 *    SYNCHRONIZED
 *
 *********************************************************/
void tableClear(HashTable* hasht);


/**
 *********************************************************
 *
 * @brief
 *    return the number of entries in the table
 *
 * @note 
 *    UNSYNCHRONIZED
 *
 *********************************************************/
int tableSize(HashTable* hasht);


/**
 *********************************************************
 *
 * @brief
 *    retrieve the entry in the table from the given key
 *
 * @return
 *    pointer to the matched entry if there is a match
 *    NULL if not found
 *
 * @note 
 *    SYNCHRONIZED
 *
 *********************************************************/
Entry_value_ptr_t tableGet(HashTable* hasht, tptp_uint32 key);


/**
 *********************************************************
 *
 * @brief
 *    rehash the table (because it exceeds its load)
 *
 * @note 
 *    UNSYNCHRONIZED
 *
 *********************************************************/
void tableRehash(HashTable* hasht);


/**
 *********************************************************
 *
 * @brief
 *    remove the entry with the given key from the table
 *
 * @return
 *    FALSE - Key is not found
 *    TRUE  - Sucessfully remove
 *
 * @note 
 *    SYNCHRONIZED
 *
 *********************************************************/
BOOL tableRemove(HashTable* hasht, tptp_uint32 key);


/**
 *********************************************************
 *
 * @brief
 *    add a given entry (key & value) to the given hash table
 *
 * @return
 *    NULL if this is a new key
 *    Pointer of the existing value (being replaced) if the key is already there
 *
 * @note 
 *    SYNCHRONIZED
 *
 *********************************************************/
Entry_value_ptr_t tablePut(HashTable* hasht, tptp_uint32 key, Entry_value_ptr_t pValue);


#ifdef __cplusplus
}
#endif
#endif
