diff options
author | Slávek Banko <slavek.banko@axis.cz> | 2021-11-05 13:28:23 +0100 |
---|---|---|
committer | Slávek Banko <slavek.banko@axis.cz> | 2021-11-05 13:28:23 +0100 |
commit | 8c787c3591c1c885b91a54128835b400858c5cca (patch) | |
tree | eca1b776912a305c4d45b3964038278a2fae1ead /debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc | |
parent | fe188b907cdf30dfdfe0eba9412e7f8749fec158 (diff) | |
download | extra-dependencies-8c787c3591c1c885b91a54128835b400858c5cca.tar.gz extra-dependencies-8c787c3591c1c885b91a54128835b400858c5cca.zip |
DEB htdig: Added to repository.
Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc')
-rw-r--r-- | debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc b/debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc new file mode 100644 index 00000000..8c0da019 --- /dev/null +++ b/debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc @@ -0,0 +1,416 @@ +// +// Dictionary.cc +// +// Dictionary: This class provides an object lookup table. +// Each object in the dictionary is indexed with a string. +// The objects can be returned by mentioning their +// string index. +// +// Part of the ht://Dig package <http://www.htdig.org/> +// Copyright (c) 1995-2004 The ht://Dig Group +// For copyright details, see the file COPYING in your distribution +// or the GNU Library General Public License (LGPL) version 2 or later +// <http://www.gnu.org/copyleft/lgpl.html> +// +// $Id: Dictionary.cc,v 1.16 2004/05/28 13:15:20 lha Exp $ +// + +#ifdef HAVE_CONFIG_H +#include "htconfig.h" +#endif /* HAVE_CONFIG_H */ + +#include "Dictionary.h" + +#include <stdlib.h> + +class DictionaryEntry +{ +public: + unsigned int hash; + char *key; + Object *value; + DictionaryEntry *next; + + ~DictionaryEntry(); + void release(); +}; + +DictionaryEntry::~DictionaryEntry() +{ + free(key); + delete value; +} + +void +DictionaryEntry::release() +{ + value = NULL; // Prevent the value from being deleted +} + + +//********************************************************************* +// +Dictionary::Dictionary() +{ + init(101, 10.0f); +} + +Dictionary::Dictionary(int initialCapacity, float loadFactor) +{ + init(initialCapacity, loadFactor); +} + +Dictionary::Dictionary(int initialCapacity) +{ + init(initialCapacity, 0.75f); +} + +Dictionary::Dictionary(const Dictionary& other) +{ + init(other.initialCapacity, other.loadFactor); + + DictionaryCursor cursor; + const char* key; + for(other.Start_Get(cursor); (key = other.Get_Next(cursor));) { + Add(key, other[key]); + } +} + +//********************************************************************* +// +Dictionary::~Dictionary() +{ + Destroy(); + + delete [] table; +} + + +//********************************************************************* +// +void +Dictionary::Destroy() +{ + DictionaryEntry *t, *n; + + for (int i = 0; i < tableLength; i++) + { + if (table[i] != NULL) + { + t = table[i]; + do { // clear out hash chain + n = t->next; + delete t; + t = n; + } while (n); + table[i] = NULL; + } + } + count = 0; +} + +//********************************************************************* +// +void +Dictionary::Release() +{ + DictionaryEntry *t, *n; + + for (int i = 0; i < tableLength; i++) + { + if (table[i] != NULL) + { + t = table[i]; + do { // clear out hash chain + n = t->next; + t->release(); + delete t; + t = n; + } while (n); + table[i] = NULL; + } + } + count = 0; +} + + +//********************************************************************* +// +void +Dictionary::init(int initialCapacity, float loadFactor) +{ + if (initialCapacity <= 0) + initialCapacity = 101; + if (loadFactor <= 0.0) + loadFactor = 0.75f; + Dictionary::loadFactor = loadFactor; + table = new DictionaryEntry*[initialCapacity]; + for (int i = 0; i < initialCapacity; i++) + { + table[i] = NULL; + } + threshold = (int)(initialCapacity * loadFactor); + tableLength = initialCapacity; + count = 0; +} + +//********************************************************************* +// +unsigned int +Dictionary::hashCode(const char *key) const +{ + char *test; + long conv_key = strtol(key, &test, 10); + if (key && *key && !*test) // Conversion succeeded + return conv_key; + + char *base = (char*)malloc(strlen(key) + 2); + char *tmp_key = base; + strcpy(tmp_key, key); + + unsigned int h = 0; + int length = strlen(tmp_key); + + if (length >= 16) + { + tmp_key += strlen(tmp_key) - 15; + length = strlen(tmp_key); + } + for (int i = length; i > 0; i--) + { + h = (h*37) + *tmp_key++; + } + + free(base); + return h; +} + +//********************************************************************* +// Add an entry to the hash table. This will replace the +// data associated with an already existing key. +// +void +Dictionary::Add(const String& name, Object *obj) +{ + unsigned int hash = hashCode(name); + int index = hash % tableLength; + DictionaryEntry *e; + + for (e = table[index]; e != NULL; e = e->next) + { + if (e->hash == hash && strcmp(e->key, name) == 0) + { + delete e->value; + e->value = obj; + return; + } + } + + if (count >= threshold) + { + rehash(); + Add(name, obj); + return; + } + + e = new DictionaryEntry(); + e->hash = hash; + e->key = strdup(name); + e->value = obj; + e->next = table[index]; + table[index] = e; + count++; +} + + +//********************************************************************* +// Remove an entry from the hash table. +// +int +Dictionary::Remove(const String& name) +{ + if (!count) + return 0; + + unsigned int hash = hashCode(name); + int index = hash % tableLength; + DictionaryEntry *e, *prev; + + for (e = table[index], prev = NULL; e != NULL; prev = e, e = e->next) + { + if (hash == e->hash && strcmp(e->key, name) == 0) + { + if (prev != NULL) + { + prev->next = e->next; + } + else + { + table[index] = e->next; + } + count--; + delete e; + return 1; + } + } + return 0; +} + + +//********************************************************************* +// +Object *Dictionary::Find(const String& name) const +{ + if (!count) + return NULL; + + unsigned int hash = hashCode(name); + int index = hash % tableLength; + DictionaryEntry *e; + + for (e = table[index]; e != NULL; e = e->next) + { + if (e->hash == hash && strcmp(e->key, name) == 0) + { + return e->value; + } + } + return NULL; +} + + +//********************************************************************* +// +Object *Dictionary::operator[](const String& name) const +{ + return Find(name); +} + + +//********************************************************************* +// +int Dictionary::Exists(const String& name) const +{ + if (!count) + return 0; + + unsigned int hash = hashCode(name); + int index = hash % tableLength; + DictionaryEntry *e; + + for (e = table[index]; e != NULL; e = e->next) + { + if (e->hash == hash && strcmp(e->key, name) == 0) + { + return 1; + } + } + return 0; +} + + +//********************************************************************* +// +void +Dictionary::rehash() +{ + DictionaryEntry **oldTable = table; + int oldCapacity = tableLength; + + int newCapacity; + DictionaryEntry *e; + int i, index; + + newCapacity = count > oldCapacity ? count * 2 + 1 : oldCapacity * 2 + 1; + + DictionaryEntry **newTable = new DictionaryEntry*[newCapacity]; + + for (i = 0; i < newCapacity; i++) + { + newTable[i] = NULL; + } + + threshold = (int) (newCapacity * loadFactor); + table = newTable; + tableLength = newCapacity; + + for (i = oldCapacity; i-- > 0;) + { + for (DictionaryEntry *old = oldTable[i]; old != NULL;) + { + e = old; + old = old->next; + index = e->hash % newCapacity; + e->next = newTable[index]; + newTable[index] = e; + } + } + delete [] oldTable; +} + + +//********************************************************************* +// +void +Dictionary::Start_Get(DictionaryCursor& cursor) const +{ + cursor.currentTableIndex = -1; + cursor.currentDictionaryEntry = NULL; +} + + +//********************************************************************* +// +char * +Dictionary::Get_Next(DictionaryCursor& cursor) const +{ + while (cursor.currentDictionaryEntry == NULL || + cursor.currentDictionaryEntry->next == NULL) + { + cursor.currentTableIndex++; + + if (cursor.currentTableIndex >= tableLength) + { + cursor.currentTableIndex--; + return NULL; + } + + cursor.currentDictionaryEntry = table[cursor.currentTableIndex]; + + if (cursor.currentDictionaryEntry != NULL) + { + return cursor.currentDictionaryEntry->key; + } + } + + cursor.currentDictionaryEntry = cursor.currentDictionaryEntry->next; + return cursor.currentDictionaryEntry->key; +} + +//********************************************************************* +// +Object * +Dictionary::Get_NextElement(DictionaryCursor& cursor) const +{ + while (cursor.currentDictionaryEntry == NULL || + cursor.currentDictionaryEntry->next == NULL) + { + cursor.currentTableIndex++; + + if (cursor.currentTableIndex >= tableLength) + { + cursor.currentTableIndex--; + return NULL; + } + + cursor.currentDictionaryEntry = table[cursor.currentTableIndex]; + + if (cursor.currentDictionaryEntry != NULL) + { + return cursor.currentDictionaryEntry->value; + } + } + + cursor.currentDictionaryEntry = cursor.currentDictionaryEntry->next; + return cursor.currentDictionaryEntry->value; +} |