//******************************************** // Hash_PCSA.cpp // ------------------------------------------- // Implementations of functions related to PCSA // records, which are stored in a hash table // // Author: Leiwen Deng // Date: 12/10/2005 //******************************************** #include "Hash_PCSA.h" //******************************************** // key1 == key2 ? // ------------------------------------------- // The equal comparison method for MD5_KEY type //******************************************** bool operator==( const MD5_KEY &key1, const MD5_KEY &key2 ) { return ( memcmp( &(key1.key), &(key2.key), MD5_DIGEST_CHARS ) == 0 ); } //******************************************** // MD5_KEY() // ------------------------------------------- // The default constructor //******************************************** MD5_KEY::MD5_KEY( void ) {} //******************************************** // MD5_KEY( key_in ) // ------------------------------------------- // A copy constructor that allows the // "const char *" type to be converted to // MD5_KEY type automatically //******************************************** MD5_KEY::MD5_KEY( const char key_in[MD5_DIGEST_CHARS] ) { memcpy( key, key_in, MD5_DIGEST_CHARS ); } //******************************************** // md5key = rkey // ------------------------------------------- // The evaluation method that pass value from // "const char *" to MD5_KEY //******************************************** MD5_KEY& MD5_KEY::operator=( const char rkey[MD5_DIGEST_CHARS] ) { return *( new (this) MD5_KEY( rkey ) ); } //******************************************** // hashed_value = HashMD5( key ) // ------------------------------------------- // A hash function for MD5_KEY type //******************************************** int HashMD5( const MD5_KEY &key ) { int hashed_value = *(int *)key.key; hashed_value += *(int *)(key.key + 4); hashed_value += *(int *)(key.key + 8); hashed_value += *(int *)(key.key + 12); hashed_value &= 0x7FFFFFFF; return hashed_value; } //******************************************** // character = Hex_4bit( value ) // ------------------------------------------- // Convert the (0--15) to its corresponding // hexadecimal character ('0','1',...'E','F') //******************************************** static char Hex_4bit( char value ) { value &= 15; if ( value <= 9 ) value += '0'; else value += ( 'A' - 10 ); return value; } //******************************************** // string = Print( key ) // ------------------------------------------- // Print the content of a MD5 key to a static // string, input type is "MD5_KEY" //******************************************** const char * Print( const MD5_KEY &key ) { return MD5_Hex( key.key ); } //******************************************** // string = MD5_Hex( md5key ) // ------------------------------------------- // Print the content of a MD5 key to a static // string, input type is "const char *" //******************************************** const char * MD5_Hex( const char md5key[MD5_DIGEST_CHARS] ) { static char hex_string[MD5_DIGEST_CHARS * 2 + 1]; char * current_byte = hex_string; for ( int i = 0; i < MD5_DIGEST_CHARS; i ++ ) { *(current_byte ++) = Hex_4bit( md5key[i] >> 4 ); *(current_byte ++) = Hex_4bit( md5key[i] & 15 ); } *current_byte = 0; return hex_string; } //******************************************** // PCSA_RECORD() // ------------------------------------------- // The constructor //******************************************** PCSA_RECORD::PCSA_RECORD( void ) { squid_refcount = 0; refcount = 0; pcsa = NULL; ac_set = NULL; } //******************************************** // ~PCSA_RECORD() // ------------------------------------------- // The destructor //******************************************** PCSA_RECORD::~PCSA_RECORD( void ) { if ( pcsa ) delete pcsa; if ( ac_set ) delete ac_set; } //******************************************** // cardinality = Cardinality() // ------------------------------------------- // Retrieve the number of unique client IPs // that refer to this entry //******************************************** int PCSA_RECORD::Cardinality( void ) const { if ( pcsa ) return pcsa->GetCardinality(); if ( ac_set ) return ac_set->size(); return 0; } //******************************************** // string = Print( pcsa_record ) // ------------------------------------------- // Print the content of a PCSA record to a // static string //******************************************** const char * Print( const PCSA_RECORD &pcsa_record ) { static char buffer[100]; sprintf( buffer, "squid_refcount: %d, refcount: %d, ac: %d, pc: %d", pcsa_record.squid_refcount, pcsa_record.refcount, ( pcsa_record.ac_set ? pcsa_record.ac_set->size() : 0 ), ( pcsa_record.pcsa ? pcsa_record.pcsa->GetCardinality() : 0 ) ); return buffer; }