--------------------- PatchSet 1021 Date: 2004/06/03 22:52:27 Author: ahouhpuc Branch: varyetag Tag: (none) Log: two new files got forgotten... Members: src/CharHashTable.cc:1.1->1.1.2.1 src/CharHashTable.h:1.1->1.1.2.1 --- /dev/null Wed Feb 14 12:17:25 2007 +++ squid3/src/CharHashTable.cc Wed Feb 14 12:18:14 2007 @@ -0,0 +1,307 @@ +/* + * $Id: CharHashTable.cc,v 1.1.2.1 2004/06/03 22:52:27 ahouhpuc Exp $ + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + */ + +#include "squid.h" +#include "CharHashTable.h" + +/* + * Creates new CharHashTable. + * It's contents is packed in the argument. + * Format of packed: "L LK LV LK LV ...", + * where L is the length of the whole packed string minus sizeof(int) + * (it is the length of "LK LV LK LV ..." part only), + * LK is the length of the key of a pair and the key-string itself, + * LV is the length of the value of a pair and the value-string itself. + * + * Doesn't free packed. + */ +CharHashTable::CharHashTable(char *packed) : map(hash_create((HASHCMP *) strcmp,CHARHASHTABLE_DEFAULT_SIZE,hash4)) { + + debug(93, 9) ("CharHashTable::CharHashTable(%p): constructor\n", packed); + + // if there are no packed pairs to add to fresh and empty contents + if (!packed) + return; + + // counter to traverse packed string + int pos = 0; + + // length of packed string - first sizeof(int) bytes of packed string + int length; + + // temporal length for keys and values + int len; + + // temporal... + char *key, *element; + + // get packed string length + xmemcpy(&length, &packed[pos], sizeof(int)); + + // int was read + pos += sizeof(int); + + // read (key, element) as long as the whole packed is read + while (pos < length + 4) { + + // the length of the key + xmemcpy(&len, &packed[pos], sizeof(int)); + pos += sizeof(int); + + // after the key length should be the key itself or the element LV + assert(pos < length + 4); + + // key itself + key = (char*)xmalloc(len+1); + xmemcpy(key, &packed[pos], len); + key[len] = 0; + pos += len; + + // after the key should be the element LV + assert(pos < length + 4); + + // the length of the value + xmemcpy(&len, &packed[pos], sizeof(int)); + pos += sizeof(int); + + // if value is non empty there should be the element now + assert(pos < length + 4 || len == 0); + + // element itself + element = (char*)xmalloc(len+1); + xmemcpy(element, &packed[pos], len); + element[len] = 0; + pos += len; + + // save the pair (copies the strings) + put(key, element); + + // freedom for all + safe_free(key); + safe_free(element); + } +} + +/* + * Frees table pair... to be used with hashFreeItems. + */ +void +CharHashTable::elementFree(void *e) { + CharHashTableElement *chtel = (CharHashTableElement*)e; + assert(chtel); + + debug(93, 9) ("CharHashTable::elementFree(): key: %s, element: %s\n", + (char*)chtel->key, (char*)chtel->element); + + assert(chtel->key); + safe_free(chtel->key); + delete chtel; +} + +/* + * Frees the whole table. + */ +CharHashTable::~CharHashTable() { + + debug(93, 9) ("~CharHashTable: size=%d\n", map->count); + assert(map); + + hashFreeItems(map, elementFree); + hashFreeMemory(map); + +} + +/* + * Retrieves element identified by the given key or NULL. + * Doesn't copy the returned element. + */ +char * +CharHashTable::get(char *key) { + CharHashTableElement *hte = static_cast(hash_lookup(map, key)); + + if (hte) { + debug(93, 9) ("CharHashTable::get key=[%s] element=[%s]\n", key, hte->element); + return hte->element; + } + debug(93, 9) ("CharHashTable::get key=[%s] element=[NULL]\n", key); + return NULL; +} + +/* + * Retrieves concatenation of the keys. + */ +char * +CharHashTable::keys() { + CharHashTableElement *hte; + hash_first(map); + int size = 0; + int pos = 0; + + while ((hte = (CharHashTableElement*)hash_next(map))) { + size += (strlen((char*)hte->key)+1); // 1 for , + debug(93, 9) ("\t^^^ key=[%s]\n", (char*)hte->key); + } + if (!size) { + debug(93, 9) ("\t^^^ CharHashTable::keys: result is empty!\n"); + return NULL; + } + char* result = (char*)xmalloc(size); + + hash_first(map); + + while ((hte = (CharHashTableElement*)hash_next(map))) { + xmemcpy(result+pos,(char*)hte->key, strlen((char*)hte->key)); + pos += (strlen((char*)hte->key)); // 1 for , + result[pos++]= ','; + debug(93, 9) ("\t^^^ key=[%s]\n", (char*)hte->key); + } + result[size-1] = 0; + debug(93, 9) ("\t^^^ CharHashTable::keys: result=[%s]\n", result); + return result; +} + +/* + * Puts the given pair into table. + * Copies both key and element. + */ +void +CharHashTable::put(char *key, char *element) { + + debug(93, 9) ("CharHashTable::put key=[%s] element=[%s]\n", key, element); + + // new element + CharHashTableElement *hte = (CharHashTableElement*)xmalloc(sizeof(CharHashTableElement)); + hte->key = xstrdup(key); + hte->element = xstrdup(element); + + debug(93, 9) ("CharHashTable::put map size=%d\n", map->count); + hash_join(map, hte); + debug(93, 9) ("CharHashTable::put map size=%d\n", map->count); +} + +/* + * Removes pair identified by the given key. + * Doesn't free the given key. + * + * XXX does it free the stored key? + */ +void +CharHashTable::remove(char *key) { + CharHashTableElement *hte = static_cast(hash_lookup(map, key)); + + debug(93, 9) ("CharHashTable::remove key=[%s], hte=%p\n", key, hte); + + if (hte) { + hash_remove_link(map, hte); + delete hte; + } + +} + +/* + * Packs table into char *. + * On packed_length returns the length + * of the whole char *. + * + * The resulting string is to be passed to constructor + * in order to restore the table. + * + * It's format: "L LK LV LK LV ..." + */ +char * +CharHashTable::pack(int *packed_length) { + + // temporal... + CharHashTableElement *hte; + + // length of the "LK LV LK LV ..." to be stored in the first + // sizeof(int) bytes of resulting string + int length = 0; + + hash_first(map); + + // sum up all the length needed for each "LK LV" + while ((hte = (CharHashTableElement*)hash_next(map))) { + length += (2*sizeof(int)); + length += (strlen((char*)hte->key) + strlen((char*)hte->element)); + } + + // return the whole length... + *packed_length = (length + sizeof(int)); + + char *packed = (char*)xmalloc(*packed_length); + + // the leading "L" + xmemcpy(packed, &length, sizeof(int)); + + // counter... traverses the packed string as the packing proceeds + int pos = sizeof(int); + + hash_first(map); + + // pack all pairs + while ((hte = (CharHashTableElement*)hash_next(map))) { + // temporal for key's and element's lengths + int len; + + // the length of the key + len = strlen((char*)hte->key); + xmemcpy(&packed[pos], &len, sizeof(int)); + pos += sizeof(int); + + // the key itself + xmemcpy(&packed[pos], hte->key, len); + pos += len; + + // the length of the element + len = strlen(hte->element); + xmemcpy(&packed[pos], &len, sizeof(int)); + pos += sizeof(int); + + // the element itself + xmemcpy(&packed[pos], hte->element, len); + pos += len; + } + + return packed; +} + +/* + * Dumps all the pairs with debugs + */ +void +CharHashTable::dump() { + CharHashTableElement *hte; + hash_first(map); + + while ((hte = (CharHashTableElement*)hash_next(map))) { + debug(93, 9) ("\t^^^ key=[%s] element=[%s]\n", (char*)hte->key, (char*)hte->element); + } +} --- /dev/null Wed Feb 14 12:17:25 2007 +++ squid3/src/CharHashTable.h Wed Feb 14 12:18:14 2007 @@ -0,0 +1,115 @@ +/* + * $Id: CharHashTable.h,v 1.1.2.1 2004/06/03 22:52:27 ahouhpuc Exp $ + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + */ + +#ifndef SQUID_CHARHASHTABLE_H +#define SQUID_CHARHASHTABLE_H + +#define CHARHASHTABLE_DEFAULT_SIZE 32 + +/* + * Hashtable to store pair of char *. + * Based on hash_table from hash_table.cc. + */ +class CharHashTable +{ + +public: + /* + * Creates empty hashtable. + */ + CharHashTable() : map(hash_create((HASHCMP *) strcmp,CHARHASHTABLE_DEFAULT_SIZE,hash4)) {} + + /* + * Creates new hashtable filled with pairs encoded in the pack argument. + */ + CharHashTable(char *packed); + + /* + * Destroys hashtable along with it's elements. + */ + ~CharHashTable(); + + /* + * Retrieves element associated with the given key. + */ + char * get(char *key); + + /* + * Retrieves concatenation of the keys from hash table. + */ + char * keys(); + + /* + * Associates the given key with the given element. + * Copies both of them. + */ + void put(char *key, char *element); + + /* + * Encodes all the associations into a string. + * On packed_length the length of packed string is returned. + */ + char * pack(int *packed_length); + + /* + * Removes pair identified by the given key. + * Doesn't free the key. + */ + void remove(char *key); + + /* + * To be used with hashFreeItems. + */ + static void elementFree(void *); + + /* + * Debugs all the pairs + */ + void dump(); + +protected: + + /* + * Backing hashtable. + */ + hash_table *map; + +}; + +/* + * Hashtable element. + */ +struct CharHashTableElement : public hash_link +{ + ~CharHashTableElement() { safe_free(element); } + char *element; +}; + +#endif /* SQUID_CHARHASHTABLE_H*/