blob: 540836369bb599bb3bdeb22b135b7839054e472d [file] [log] [blame]
/*
* utilHashtable.c
*
* (C) Copyright IBM Corp. 2005
*
* THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE
* ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE
* CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT.
*
* You can obtain a current copy of the Eclipse Public License from
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* Author: Adrian Schuur <schuur@de.ibm.com>
*
* Description:
*
* Hashtable factory support.
*
*/
#include "utilft.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
extern void *HashTableCreate(long numOfBuckets);
extern Util_HashTable_FT *UtilHashTableFT;
static unsigned long charHashFunction(const void *key)
{
const unsigned char *str = (const unsigned char *) key;
unsigned long hashValue = 0;
int i;
for (i = 0; str[i] != '\0'; i++)
hashValue = hashValue * 37 + str[i];
return hashValue;
}
static int charCmpFunction(const void *pointer1, const void *pointer2)
{
return strcmp((char *) pointer1, (char *) pointer2);
}
static int ptrCmpFunction(const void *pointer1, const void *pointer2)
{
return (pointer1 != pointer2);
}
/*
static unsigned long ptrHashFunction(const void *pointer) {
return ((unsigned long) pointer) >> 4;
}
*/
typedef struct _CMPI_String {
void *hdl;
void *ft;
} CMPI_String;
static unsigned long charIcHashFunction(const void *key)
{
const unsigned char *str = (const unsigned char *) key;
unsigned long hashValue = 0;
int i;
for (i = 0; str[i] != '\0'; i++)
hashValue = hashValue * 37 + toupper(str[i]);
return hashValue;
}
static int charIcCmpFunction(const void *pointer1, const void *pointer2)
{
return strcasecmp((char *) pointer1, (char *) pointer2);
}
static unsigned long cmpiStringIcHashFunction(const void *key)
{
return charIcHashFunction((const void *) ((CMPI_String *) key)->hdl);
}
static int cmpiStringIcCmpFunction(const void *p1, const void *p2)
{
return strcasecmp((char *) ((CMPI_String *) p1)->hdl,
(char *) ((CMPI_String *) p2)->hdl);
}
static unsigned long cmpiStringHashFunction(const void *key)
{
return charHashFunction((const void *) ((CMPI_String *) key)->hdl);
}
static int cmpiStringCmpFunction(const void *p1, const void *p2)
{
return strcmp((char *) ((CMPI_String *) p1)->hdl,
(char *) ((CMPI_String *) p2)->hdl);
}
UtilHashTable *newHashTableDefault(long buckets)
{
UtilHashTable *ht = (UtilHashTable *) malloc(sizeof(UtilHashTable));
void *t = HashTableCreate(buckets);
ht->hdl = t;
ht->ft = UtilHashTableFT;
UtilHashTableFT->setHashFunction(ht, charHashFunction);
UtilHashTableFT->setKeyCmpFunction(ht, charCmpFunction);
UtilHashTableFT->setValueCmpFunction(ht, ptrCmpFunction);
UtilHashTableFT->setReleaseFunctions(ht, free, free);
return ht;
}
UtilHashTable *newHashTable(long buckets, long opt)
{
UtilHashTable *ht = (UtilHashTable *) malloc(sizeof(UtilHashTable));
void *t = HashTableCreate(buckets);
void (*keyRelease) (void *key) = NULL;
void (*valueRelease) (void *value) = NULL;
ht->hdl = t;
ht->ft = UtilHashTableFT;
if (opt & UtilHashTable_charKey) {
if (opt & UtilHashTable_ignoreKeyCase) {
UtilHashTableFT->setHashFunction(ht, charIcHashFunction);
UtilHashTableFT->setKeyCmpFunction(ht, charIcCmpFunction);
}
else {
UtilHashTableFT->setHashFunction(ht, charHashFunction);
UtilHashTableFT->setKeyCmpFunction(ht, charCmpFunction);
}
}
else if (opt & UtilHashTable_CMPIStringKey) {
if (opt & UtilHashTable_ignoreKeyCase) {
UtilHashTableFT->setHashFunction(ht, cmpiStringIcHashFunction);
UtilHashTableFT->setKeyCmpFunction(ht, cmpiStringIcCmpFunction);
}
else {
UtilHashTableFT->setHashFunction(ht, cmpiStringHashFunction);
UtilHashTableFT->setKeyCmpFunction(ht, cmpiStringCmpFunction);
}
}
if (opt & UtilHashTable_charValue) {
if (opt & UtilHashTable_ignoreValueCase)
UtilHashTableFT->setValueCmpFunction(ht, charIcCmpFunction);
else
UtilHashTableFT->setValueCmpFunction(ht, charCmpFunction);
}
else
UtilHashTableFT->setValueCmpFunction(ht, ptrCmpFunction);
if (opt & UtilHashTable_managedKey) {
if (opt & UtilHashTable_CMPIStringKey)
keyRelease = NULL;
else
keyRelease = free;
}
if (opt & UtilHashTable_managedValue) {
if (opt & UtilHashTable_CMPIStyleValue)
valueRelease = NULL;
else
valueRelease = free;
}
UtilHashTableFT->setReleaseFunctions(ht, keyRelease, valueRelease);
return ht;
}