diff options
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 620 |
1 files changed, 0 insertions, 620 deletions
diff --git a/hash.c b/hash.c deleted file mode 100644 index 7881fc64..00000000 --- a/hash.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * hash.c: chained hash tables - * - * Reference: Your favorite introductory book on algorithms - * - * Copyright (C) 2000 Bjorn Reese and Daniel Veillard. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND - * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. - * - * Author: bjorn.reese@systematic.dk - */ - -#ifdef WIN32 -#include "win32config.h" -#else -#include "config.h" -#endif - -#include <string.h> -#include <libxml/hash.h> -#include <libxml/xmlmemory.h> -#include <libxml/parser.h> - -/* - * A single entry in the hash table - */ -typedef struct _xmlHashEntry xmlHashEntry; -typedef xmlHashEntry *xmlHashEntryPtr; -struct _xmlHashEntry { - struct _xmlHashEntry *next; - xmlChar *name; - xmlChar *name2; - xmlChar *name3; - void *payload; -}; - -/* - * The entire hash table - */ -struct _xmlHashTable { - struct _xmlHashEntry **table; - int size; - int nbElems; -}; - -/* - * xmlHashComputeKey: - * Calculate the hash key - */ -static unsigned long -xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *string) { - unsigned long value = 0L; - char ch; - - while ((ch = *string++) != 0) { - /* value *= 31; */ - value += (unsigned long)ch; - } - return (value % table->size); -} - -/** - * xmlHashCreate: - * @size: the size of the hash table - * - * Create a new xmlHashTablePtr. - * - * Returns the newly created object, or NULL if an error occured. - */ -xmlHashTablePtr -xmlHashCreate(int size) { - xmlHashTablePtr table; - - if (size <= 0) - size = 256; - - table = xmlMalloc(sizeof(xmlHashTable)); - if (table) { - table->size = size; - table->nbElems = 0; - table->table = xmlMalloc(size * sizeof(xmlHashEntry)); - if (table->table) { - memset(table->table, 0, size * sizeof(xmlHashEntry)); - return(table); - } - xmlFree(table); - } - return(NULL); -} - -/** - * xmlHashFree: - * @table: the hash table - * @f: the deallocator function for items in the hash - * - * Free the hash table and its contents. The userdata is - * deallocated with f if provided. - */ -void -xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) { - int i; - xmlHashEntryPtr iter; - xmlHashEntryPtr next; - - if (table == NULL) - return; - if (table->table) { - for(i = 0; i < table->size; i++) { - iter = table->table[i]; - while (iter) { - next = iter->next; - if (iter->name) - xmlFree(iter->name); - if (iter->name2) - xmlFree(iter->name2); - if (iter->name3) - xmlFree(iter->name3); - if (f) - f(iter->payload, iter->name); - iter->payload = NULL; - xmlFree(iter); - iter = next; - } - table->table[i] = NULL; - } - xmlFree(table->table); - } - xmlFree(table); -} - -/** - * xmlHashAddEntry: - * @table: the hash table - * @name: the name of the userdata - * @userdata: a pointer to the userdata - * - * Add the userdata to the hash table. This can later be retrieved - * by using the name. Duplicate names generate errors. - * - * Returns 0 the addition succeeded and -1 in case of error. - */ -int -xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) { - return(xmlHashAddEntry3(table, name, NULL, NULL, userdata)); -} - -/** - * xmlHashAddEntry2: - * @table: the hash table - * @name: the name of the userdata - * @name2: a second name of the userdata - * @userdata: a pointer to the userdata - * - * Add the userdata to the hash table. This can later be retrieved - * by using the (name, name2) tuple. Duplicate tuples generate errors. - * - * Returns 0 the addition succeeded and -1 in case of error. - */ -int -xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name, - const xmlChar *name2, void *userdata) { - return(xmlHashAddEntry3(table, name, name2, NULL, userdata)); -} - -/** - * xmlHashUpdateEntry: - * @table: the hash table - * @name: the name of the userdata - * @userdata: a pointer to the userdata - * @f: the deallocator function for replaced item (if any) - * - * Add the userdata to the hash table. This can later be retrieved - * by using the name. Existing entry for this name will be removed - * and freed with @f if found. - * - * Returns 0 the addition succeeded and -1 in case of error. - */ -int -xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name, - void *userdata, xmlHashDeallocator f) { - return(xmlHashUpdateEntry3(table, name, NULL, NULL, userdata, f)); -} - -/** - * xmlHashUpdateEntry2: - * @table: the hash table - * @name: the name of the userdata - * @name2: a second name of the userdata - * @userdata: a pointer to the userdata - * @f: the deallocator function for replaced item (if any) - * - * Add the userdata to the hash table. This can later be retrieved - * by using the (name, name2) tuple. Existing entry for this tuple will - * be removed and freed with @f if found. - * - * Returns 0 the addition succeeded and -1 in case of error. - */ -int -xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name, - const xmlChar *name2, void *userdata, - xmlHashDeallocator f) { - return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f)); -} - -/** - * xmlHashLookup: - * @table: the hash table - * @name: the name of the userdata - * - * Find the userdata specified by the name. - * - * Returns the a pointer to the userdata - */ -void * -xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) { - return(xmlHashLookup3(table, name, NULL, NULL)); -} - -/** - * xmlHashLookup2: - * @table: the hash table - * @name: the name of the userdata - * @name2: a second name of the userdata - * - * Find the userdata specified by the (name, name2) tuple. - * - * Returns the a pointer to the userdata - */ -void * -xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name, - const xmlChar *name2) { - return(xmlHashLookup3(table, name, name2, NULL)); -} - -/** - * xmlHashAddEntry3: - * @table: the hash table - * @name: the name of the userdata - * @name2: a second name of the userdata - * @name3: a third name of the userdata - * @userdata: a pointer to the userdata - * - * Add the userdata to the hash table. This can later be retrieved - * by using the tuple (name, name2, name3). Duplicate entries generate - * errors. - * - * Returns 0 the addition succeeded and -1 in case of error. - */ -int -xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name, - const xmlChar *name2, const xmlChar *name3, - void *userdata) { - unsigned long key; - xmlHashEntryPtr entry; - xmlHashEntryPtr insert; - - if ((table == NULL) || name == NULL) - return(-1); - - /* - * Check for duplicate and insertion location. - */ - key = xmlHashComputeKey(table, name); - if (table->table[key] == NULL) { - insert = NULL; - } else { - for (insert = table->table[key]; insert->next != NULL; - insert = insert->next) { - if ((xmlStrEqual(insert->name, name)) && - (xmlStrEqual(insert->name2, name2)) && - (xmlStrEqual(insert->name3, name3))) - return(-1); - } - if ((xmlStrEqual(insert->name, name)) && - (xmlStrEqual(insert->name2, name2)) && - (xmlStrEqual(insert->name3, name3))) - return(-1); - } - - entry = xmlMalloc(sizeof(xmlHashEntry)); - if (entry == NULL) - return(-1); - entry->name = xmlStrdup(name); - entry->name2 = xmlStrdup(name2); - entry->name3 = xmlStrdup(name3); - entry->payload = userdata; - entry->next = NULL; - - - if (insert == NULL) { - table->table[key] = entry; - } else { - insert->next = entry; - } - table->nbElems++; - return(0); -} - -/** - * xmlHashUpdateEntry3: - * @table: the hash table - * @name: the name of the userdata - * @name2: a second name of the userdata - * @name3: a third name of the userdata - * @userdata: a pointer to the userdata - * @f: the deallocator function for replaced item (if any) - * - * Add the userdata to the hash table. This can later be retrieved - * by using the tuple (name, name2, name3). Existing entry for this tuple - * will be removed and freed with @f if found. - * - * Returns 0 the addition succeeded and -1 in case of error. - */ -int -xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name, - const xmlChar *name2, const xmlChar *name3, - void *userdata, xmlHashDeallocator f) { - unsigned long key; - xmlHashEntryPtr entry; - xmlHashEntryPtr insert; - - if ((table == NULL) || name == NULL) - return(-1); - - /* - * Check for duplicate and insertion location. - */ - key = xmlHashComputeKey(table, name); - if (table->table[key] == NULL) { - insert = NULL; - } else { - for (insert = table->table[key]; insert->next != NULL; - insert = insert->next) { - if ((xmlStrEqual(insert->name, name)) && - (xmlStrEqual(insert->name2, name2)) && - (xmlStrEqual(insert->name3, name3))) { - if (f) - f(insert->payload, insert->name); - insert->payload = userdata; - return(0); - } - } - if ((xmlStrEqual(insert->name, name)) && - (xmlStrEqual(insert->name2, name2)) && - (xmlStrEqual(insert->name3, name3))) { - if (f) - f(insert->payload, insert->name); - insert->payload = userdata; - return(0); - } - } - - entry = xmlMalloc(sizeof(xmlHashEntry)); - if (entry == NULL) - return(-1); - entry->name = xmlStrdup(name); - entry->name2 = xmlStrdup(name2); - entry->name3 = xmlStrdup(name3); - entry->payload = userdata; - entry->next = NULL; - table->nbElems++; - - - if (insert == NULL) { - table->table[key] = entry; - } else { - insert->next = entry; - } - return(0); -} - -/** - * xmlHashLookup: - * @table: the hash table - * @name: the name of the userdata - * @name2: a second name of the userdata - * @name3: a third name of the userdata - * - * Find the userdata specified by the (name, name2, name3) tuple. - * - * Returns the a pointer to the userdata - */ -void * -xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name, - const xmlChar *name2, const xmlChar *name3) { - unsigned long key; - xmlHashEntryPtr entry; - - if (table == NULL) - return(NULL); - if (name == NULL) - return(NULL); - key = xmlHashComputeKey(table, name); - for (entry = table->table[key]; entry != NULL; entry = entry->next) { - if ((xmlStrEqual(entry->name, name)) && - (xmlStrEqual(entry->name2, name2)) && - (xmlStrEqual(entry->name3, name3))) - return(entry->payload); - } - return(NULL); -} - -/** - * xmlHashScan: - * @table: the hash table - * @f: the scanner function for items in the hash - * @data: extra data passed to f - * - * Scan the hash table and applied f to each value. - */ -void -xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) { - int i; - xmlHashEntryPtr iter; - xmlHashEntryPtr next; - - if (table == NULL) - return; - if (f == NULL) - return; - - if (table->table) { - for(i = 0; i < table->size; i++) { - iter = table->table[i]; - while (iter) { - next = iter->next; - if (f) - f(iter->payload, data, iter->name); - iter = next; - } - } - } -} - -/** - * xmlHashScan3: - * @table: the hash table - * @name: the name of the userdata or NULL - * @name2: a second name of the userdata or NULL - * @name3: a third name of the userdata or NULL - * @f: the scanner function for items in the hash - * @data: extra data passed to f - * - * Scan the hash table and applied f to each value matching - * (name, name2, name3) tuple. If one of the names is null, - * the comparison is considered to match. - */ -void -xmlHashScan3(xmlHashTablePtr table, const xmlChar *name, - const xmlChar *name2, const xmlChar *name3, - xmlHashScanner f, void *data) { - int i; - xmlHashEntryPtr iter; - xmlHashEntryPtr next; - - if (table == NULL) - return; - if (f == NULL) - return; - - if (table->table) { - for(i = 0; i < table->size; i++) { - iter = table->table[i]; - while (iter) { - next = iter->next; - if (((name == NULL) || (xmlStrEqual(name, iter->name))) && - ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) && - ((name3 == NULL) || (xmlStrEqual(name3, iter->name3)))) { - f(iter->payload, data, iter->name); - } - iter = next; - } - } - } -} - -/** - * xmlHashCopy: - * @table: the hash table - * @f: the copier function for items in the hash - * - * Scan the hash table and applied f to each value. - * - * Returns the new table or NULL in case of error. - */ -xmlHashTablePtr -xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) { - int i; - xmlHashEntryPtr iter; - xmlHashEntryPtr next; - xmlHashTablePtr ret; - - if (table == NULL) - return(NULL); - if (f == NULL) - return(NULL); - - ret = xmlHashCreate(table->size); - if (table->table) { - for(i = 0; i < table->size; i++) { - iter = table->table[i]; - while (iter) { - next = iter->next; - xmlHashAddEntry3(ret, iter->name, iter->name2, - iter->name3, f(iter->payload, iter->name)); - iter = next; - } - } - } - ret->nbElems = table->nbElems; - return(ret); -} - -/** - * xmlHashSize: - * @table: the hash table - * - * Returns the number of elements in the hash table or - * -1 in case of error - */ -int -xmlHashSize(xmlHashTablePtr table) { - if (table == NULL) - return(-1); - return(table->nbElems); -} - -/** - * @table: the hash table - * @name: the name of the userdata - * @f: the deallocator function for removed item (if any) - * - * Find the userdata specified by the (name, name2, name3) tuple and remove - * it from the hash table. Existing userdata for this tuple will be removed - * and freed with @f. - * - * Returns 0 if the removal succeeded and -1 in case of error or not found. - */ -int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name, - xmlHashDeallocator f) { - return(xmlHashRemoveEntry3(table, name, NULL, NULL, f)); -} - -/** - * @table: the hash table - * @name: the name of the userdata - * @name2: a second name of the userdata - * @f: the deallocator function for removed item (if any) - * - * Find the userdata specified by the (name, name2, name3) tuple and remove - * it from the hash table. Existing userdata for this tuple will be removed - * and freed with @f. - * - * Returns 0 if the removal succeeded and -1 in case of error or not found. - */ -int xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name, - const xmlChar *name2, xmlHashDeallocator f) { - return(xmlHashRemoveEntry3(table, name, name2, NULL, f)); -} - -/** - * @table: the hash table - * @name: the name of the userdata - * @name2: a second name of the userdata - * @name3: a third name of the userdata - * @f: the deallocator function for removed item (if any) - * - * Find the userdata specified by the (name, name2, name3) tuple and remove - * it from the hash table. Existing userdata for this tuple will be removed - * and freed with @f. - * - * Returns 0 if the removal succeeded and -1 in case of error or not found. - */ -int xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name, - const xmlChar *name2, const xmlChar *name3, - xmlHashDeallocator f) { - unsigned long key; - xmlHashEntryPtr entry; - xmlHashEntryPtr prev = NULL; - - if (table == NULL || name == NULL) - return(-1); - - key = xmlHashComputeKey(table, name); - if (table->table[key] == NULL) { - return(-1); - } else { - for (entry = table->table[key]; entry != NULL; entry = entry->next) { - if (xmlStrEqual(entry->name, name) && - xmlStrEqual(entry->name2, name2) && - xmlStrEqual(entry->name3, name3)) { - if(f) - f(entry->payload, entry->name); - entry->payload = NULL; - if(entry->name) - xmlFree(entry->name); - if(entry->name2) - xmlFree(entry->name2); - if(entry->name3) - xmlFree(entry->name3); - if(prev) - prev->next = entry->next; - else - table->table[key] = entry->next; - xmlFree(entry); - table->nbElems--; - return(0); - } - prev = entry; - } - return(-1); - } -}
\ No newline at end of file |